【Java编程动手学】Java中的数组与集合

文章目录

  • 一、Java数组基础
      • [1.1 数组结构概述](#1.1 数组结构概述)
      • [1.2 一维数组](#1.2 一维数组)
        • [1.2.1 声明与初始化](#1.2.1 声明与初始化)
        • [1.2.2 访问与修改元素](#1.2.2 访问与修改元素)
        • [1.2.3 数组遍历](#1.2.3 数组遍历)
      • [1.3 二维数组](#1.3 二维数组)
        • [1.3.1 声明与初始化](#1.3.1 声明与初始化)
        • [1.3.2 访问与遍历](#1.3.2 访问与遍历)
      • [1.4 三维数组及更高维数组](#1.4 三维数组及更高维数组)
      • [1.5 数组类(Arrays)](#1.5 数组类(Arrays))
        • [1.5.1 常用方法](#1.5.1 常用方法)
      • [1.6 复制数组](#1.6 复制数组)
        • [1.6.1 系统复制方法](#1.6.1 系统复制方法)
        • [1.6.2 手动复制](#1.6.2 手动复制)
  • 二、Java集合框架
      • [2.1 集合框架概述](#2.1 集合框架概述)
      • [2.2 列表类(List)](#2.2 列表类(List))
        • [2.2.1 ArrayList](#2.2.1 ArrayList)
        • [2.2.2 LinkedList](#2.2.2 LinkedList)
      • [2.3 集合类(Set)](#2.3 集合类(Set))
        • [2.3.1 HashSet](#2.3.1 HashSet)
        • [2.3.2 TreeSet](#2.3.2 TreeSet)
      • [2.4 映射类(Map)](#2.4 映射类(Map))
        • [2.4.1 HashMap](#2.4.1 HashMap)
        • [2.4.2 TreeMap](#2.4.2 TreeMap)
      • [2.5 队列类(Queue)](#2.5 队列类(Queue))
        • [2.5.1 PriorityQueue](#2.5.1 PriorityQueue)
        • [2.5.2 ArrayDeque](#2.5.2 ArrayDeque)
      • [2.6 堆栈类(Stack)](#2.6 堆栈类(Stack))
      • [2.7 集合工具类(Collections)](#2.7 集合工具类(Collections))
  • 三、完整案例代码
      • [3.1 数组操作完整示例](#3.1 数组操作完整示例)
      • [3.2 集合操作完整示例](#3.2 集合操作完整示例)
  • 四、数组与集合使用对比
  • 总结

一、Java数组基础

1.1 数组结构概述

数组是Java中最基本的数据结构之一,用于存储相同类型的多个元素。数组具有以下特点:

  • 固定大小:一旦创建,大小不可改变
  • 连续内存空间:元素在内存中是连续存储的
  • 索引访问:通过从0开始的整数索引访问元素

1.2 一维数组

1.2.1 声明与初始化
java 复制代码
// 声明数组
int[] arr1;          // 推荐方式
int arr2[];          // 效果相同,但不推荐

// 静态初始化
int[] arr3 = {1, 2, 3, 4, 5};
String[] names = {"Alice", "Bob", "Charlie"};

// 动态初始化
int[] arr4 = new int[5];  // 默认初始化为0
boolean[] flags = new boolean[3]; // 默认初始化为false
String[] strArr = new String[4]; // 默认初始化为null
1.2.2 访问与修改元素
java 复制代码
int[] numbers = {10, 20, 30, 40, 50};

// 访问元素
System.out.println(numbers[0]); // 输出: 10
System.out.println(numbers[numbers.length - 1]); // 输出最后一个元素: 50

// 修改元素
numbers[2] = 300;
System.out.println(numbers[2]); // 输出: 300
1.2.3 数组遍历
java 复制代码
// 使用for循环
for (int i = 0; i < numbers.length; i++) {
    System.out.println("Element at index " + i + ": " + numbers[i]);
}

// 使用增强for循环
for (int num : numbers) {
    System.out.println("Number: " + num);
}

1.3 二维数组

1.3.1 声明与初始化
java 复制代码
// 声明二维数组
int[][] matrix1;
int matrix2[][];

// 静态初始化
int[][] matrix3 = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// 动态初始化
int[][] matrix4 = new int[3][4]; // 3行4列
int[][] matrix5 = new int[2][];  // 只指定行数,列数可后续指定
matrix5[0] = new int[3];
matrix5[1] = new int[5];
1.3.2 访问与遍历
java 复制代码
// 访问元素
System.out.println(matrix3[1][2]); // 输出: 6 (第2行第3列)

// 遍历二维数组
for (int i = 0; i < matrix3.length; i++) {
    for (int j = 0; j < matrix3[i].length; j++) {
        System.out.print(matrix3[i][j] + " ");
    }
    System.out.println();
}

// 使用增强for循环
for (int[] row : matrix3) {
    for (int num : row) {
        System.out.print(num + " ");
    }
    System.out.println();
}

1.4 三维数组及更高维数组

java 复制代码
// 三维数组声明与初始化
int[][][] cube = new int[2][3][4]; // 2个3x4的矩阵

// 静态初始化
int[][][] cube2 = {
    {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    },
    {
        {13, 14, 15, 16},
        {17, 18, 19, 20},
        {21, 22, 23, 24}
    }
};

// 访问三维数组元素
System.out.println(cube2[1][2][3]); // 输出: 24

// 遍历三维数组
for (int[][] matrix : cube2) {
    for (int[] row : matrix) {
        for (int num : row) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
    System.out.println("--- Next Matrix ---");
}

1.5 数组类(Arrays)

Java提供了java.util.Arrays类来操作数组。

1.5.1 常用方法
java 复制代码
import java.util.Arrays;

int[] arr = {5, 2, 9, 1, 5, 6};

// 排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr)); // [1, 2, 5, 5, 6, 9]

// 二分查找(数组必须有序)
int index = Arrays.binarySearch(arr, 5);
System.out.println("5的索引: " + index); // 2或3(取决于第一个找到的5)

// 填充
Arrays.fill(arr, 0);
System.out.println(Arrays.toString(arr)); // [0, 0, 0, 0, 0, 0]

// 比较
int[] arr2 = {1, 2, 3};
int[] arr3 = {1, 2, 3};
System.out.println(Arrays.equals(arr2, arr3)); // true

// 复制数组
int[] arrCopy = Arrays.copyOf(arr2, arr2.length);
int[] arrCopyRange = Arrays.copyOfRange(arr2, 1, 3);

1.6 复制数组

1.6.1 系统复制方法
java 复制代码
// 使用System.arraycopy()
int[] source = {1, 2, 3, 4, 5};
int[] destination = new int[5];
System.arraycopy(source, 0, destination, 0, source.length);

// 使用Arrays.copyOf()
int[] copy1 = Arrays.copyOf(source, source.length);
int[] copy2 = Arrays.copyOf(source, 3); // 只复制前3个元素

// 使用clone()
int[] clone = source.clone();
1.6.2 手动复制
java 复制代码
int[] original = {10, 20, 30, 40, 50};
int[] manualCopy = new int[original.length];

for (int i = 0; i < original.length; i++) {
    manualCopy[i] = original[i];
}

二、Java集合框架

Java集合框架位于java.util包中,提供了多种数据结构和算法。

2.1 集合框架概述

接口 实现类 特点
Collection - 所有集合的根接口
List ArrayList, LinkedList, Vector, Stack 有序,可重复
Set HashSet, LinkedHashSet, TreeSet 无序,不可重复
Queue PriorityQueue, ArrayDeque 队列接口
Deque ArrayDeque, LinkedList 双端队列
Map HashMap, LinkedHashMap, TreeMap, Hashtable 键值对存储

2.2 列表类(List)

2.2.1 ArrayList
java 复制代码
import java.util.ArrayList;
import java.util.List;

// 创建ArrayList
List<String> names = new ArrayList<>();

// 添加元素
names.add("Alice");
names.add("Bob");
names.add(1, "Charlie"); // 在索引1处插入

// 访问元素
System.out.println(names.get(0)); // Alice

// 遍历
for (String name : names) {
    System.out.println(name);
}

// 删除元素
names.remove(0); // 按索引删除
names.remove("Bob"); // 按对象删除

// 大小
System.out.println("Size: " + names.size());

// 检查包含
System.out.println(names.contains("Charlie"));
2.2.2 LinkedList
java 复制代码
import java.util.LinkedList;

LinkedList<Integer> numbers = new LinkedList<>();

// 添加元素
numbers.add(10);
numbers.addFirst(5); // 添加到头部
numbers.addLast(15); // 添加到尾部

// 获取元素
System.out.println("First: " + numbers.getFirst());
System.out.println("Last: " + numbers.getLast());

// 删除元素
numbers.removeFirst();
numbers.removeLast();

// 转换为数组
Integer[] arr = numbers.toArray(new Integer[0]);

2.3 集合类(Set)

2.3.1 HashSet
java 复制代码
import java.util.HashSet;
import java.util.Set;

Set<String> uniqueNames = new HashSet<>();

// 添加元素
uniqueNames.add("Alice");
uniqueNames.add("Bob");
uniqueNames.add("Alice"); // 重复元素不会被添加

// 遍历
for (String name : uniqueNames) {
    System.out.println(name);
}

// 检查是否存在
System.out.println(uniqueNames.contains("Bob"));

// 删除元素
uniqueNames.remove("Alice");
2.3.2 TreeSet
java 复制代码
import java.util.TreeSet;

TreeSet<Integer> sortedNumbers = new TreeSet<>();

// 添加元素(自动排序)
sortedNumbers.add(5);
sortedNumbers.add(2);
sortedNumbers.add(8);
sortedNumbers.add(1);

// 遍历(有序)
for (int num : sortedNumbers) {
    System.out.println(num); // 输出: 1, 2, 5, 8
}

// 获取子集
System.out.println(sortedNumbers.subSet(2, 6)); // [2, 5]

2.4 映射类(Map)

2.4.1 HashMap
java 复制代码
import java.util.HashMap;
import java.util.Map;

Map<String, Integer> ageMap = new HashMap<>();

// 添加键值对
ageMap.put("Alice", 25);
ageMap.put("Bob", 30);
ageMap.put("Charlie", 25);

// 获取值
System.out.println(ageMap.get("Alice")); // 25

// 遍历
for (Map.Entry<String, Integer> entry : ageMap.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

// 检查键是否存在
System.out.println(ageMap.containsKey("Bob"));

// 检查值是否存在
System.out.println(ageMap.containsValue(30));

// 删除条目
ageMap.remove("Charlie");
2.4.2 TreeMap
java 复制代码
import java.util.TreeMap;

TreeMap<Integer, String> rankMap = new TreeMap<>();

// 添加键值对(按键排序)
rankMap.put(3, "Bronze");
rankMap.put(1, "Gold");
rankMap.put(2, "Silver");

// 遍历(按键有序)
for (Map.Entry<Integer, String> entry : rankMap.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

// 获取子映射
System.out.println(rankMap.subMap(1, 3)); // {1=Gold, 2=Silver}

2.5 队列类(Queue)

2.5.1 PriorityQueue
java 复制代码
import java.util.PriorityQueue;
import java.util.Queue;

Queue<String> priorityQueue = new PriorityQueue<>();

// 添加元素(按自然顺序排序)
priorityQueue.add("Orange");
priorityQueue.add("Apple");
priorityQueue.add("Banana");

// 查看但不移除头部
System.out.println(priorityQueue.peek()); // Apple

// 移除并返回头部
System.out.println(priorityQueue.poll()); // Apple
System.out.println(priorityQueue.poll()); // Banana
2.5.2 ArrayDeque
java 复制代码
import java.util.ArrayDeque;
import java.util.Deque;

Deque<Integer> deque = new ArrayDeque<>();

// 添加元素
deque.addFirst(1); // 添加到头部
deque.addLast(3);  // 添加到尾部
deque.offerFirst(0); // 另一种添加到头部的方式
deque.offerLast(4);  // 另一种添加到尾部的方式

// 查看元素
System.out.println(deque.peekFirst()); // 0
System.out.println(deque.peekLast());  // 4

// 移除元素
System.out.println(deque.pollFirst()); // 0
System.out.println(deque.pollLast());  // 4

2.6 堆栈类(Stack)

虽然Java有Stack类,但推荐使用Deque接口的实现类作为堆栈。

java 复制代码
import java.util.ArrayDeque;
import java.util.Deque;

Deque<Integer> stack = new ArrayDeque<>();

// 压栈
stack.push(10);
stack.push(20);
stack.push(30);

// 查看栈顶
System.out.println(stack.peek()); // 30

// 弹栈
System.out.println(stack.pop()); // 30
System.out.println(stack.pop()); // 20

2.7 集合工具类(Collections)

java.util.Collections提供了许多有用的集合操作方法。

java 复制代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

List<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(2);
numbers.add(8);
numbers.add(1);

// 排序
Collections.sort(numbers);
System.out.println(numbers); // [1, 2, 5, 8]

// 反转
Collections.reverse(numbers);
System.out.println(numbers); // [8, 5, 2, 1]

// 洗牌(随机排序)
Collections.shuffle(numbers);
System.out.println(numbers);

// 最大值/最小值
System.out.println("Max: " + Collections.max(numbers));
System.out.println("Min: " + Collections.min(numbers));

// 不可变集合
List<Integer> immutableList = Collections.unmodifiableList(numbers);
// immutableList.add(10); // 抛出UnsupportedOperationException

三、完整案例代码

3.1 数组操作完整示例

java 复制代码
import java.util.Arrays;

public class ArrayDemo {
    public static void main(String[] args) {
        // 一维数组示例
        int[] oneDArray = {5, 2, 9, 1, 5, 6};
        System.out.println("原始数组: " + Arrays.toString(oneDArray));
        
        Arrays.sort(oneDArray);
        System.out.println("排序后: " + Arrays.toString(oneDArray));
        
        int index = Arrays.binarySearch(oneDArray, 5);
        System.out.println("5的索引: " + index);
        
        // 二维数组示例
        int[][] twoDArray = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        System.out.println("\n二维数组:");
        for (int[] row : twoDArray) {
            for (int num : row) {
                System.out.print(num + " ");
            }
            System.out.println();
        }
        
        // 数组复制示例
        int[] copy = Arrays.copyOf(oneDArray, oneDArray.length);
        System.out.println("\n数组复制: " + Arrays.toString(copy));
        
        // 手动复制
        int[] manualCopy = new int[oneDArray.length];
        for (int i = 0; i < oneDArray.length; i++) {
            manualCopy[i] = oneDArray[i];
        }
        System.out.println("手动复制: " + Arrays.toString(manualCopy));
    }
}

3.2 集合操作完整示例

java 复制代码
import java.util.*;

public class CollectionDemo {
    public static void main(String[] args) {
        // List示例 - ArrayList
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        names.add(1, "David"); // 在索引1处插入
        
        System.out.println("ArrayList内容:");
        for (String name : names) {
            System.out.println(name);
        }
        
        // List示例 - LinkedList
        LinkedList<Integer> numbers = new LinkedList<>();
        numbers.add(10);
        numbers.addFirst(5);
        numbers.addLast(15);
        
        System.out.println("\nLinkedList内容:");
        Iterator<Integer> iterator = numbers.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        
        // Set示例 - HashSet
        Set<String> uniqueNames = new HashSet<>();
        uniqueNames.add("Alice");
        uniqueNames.add("Bob");
        uniqueNames.add("Alice"); // 重复元素
        
        System.out.println("\nHashSet内容(去重):");
        for (String name : uniqueNames) {
            System.out.println(name);
        }
        
        // Set示例 - TreeSet
        TreeSet<Integer> sortedNumbers = new TreeSet<>();
        sortedNumbers.add(5);
        sortedNumbers.add(2);
        sortedNumbers.add(8);
        sortedNumbers.add(1);
        
        System.out.println("\nTreeSet内容(排序):");
        for (int num : sortedNumbers) {
            System.out.println(num);
        }
        
        // Map示例 - HashMap
        Map<String, Integer> ageMap = new HashMap<>();
        ageMap.put("Alice", 25);
        ageMap.put("Bob", 30);
        ageMap.put("Charlie", 25);
        
        System.out.println("\nHashMap内容:");
        for (Map.Entry<String, Integer> entry : ageMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        
        // Map示例 - TreeMap
        TreeMap<Integer, String> rankMap = new TreeMap<>();
        rankMap.put(3, "Bronze");
        rankMap.put(1, "Gold");
        rankMap.put(2, "Silver");
        
        System.out.println("\nTreeMap内容(按键排序):");
        for (Map.Entry<Integer, String> entry : rankMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        
        // Queue示例 - PriorityQueue
        Queue<String> priorityQueue = new PriorityQueue<>();
        priorityQueue.add("Orange");
        priorityQueue.add("Apple");
        priorityQueue.add("Banana");
        
        System.out.println("\nPriorityQueue内容(按字母顺序):");
        while (!priorityQueue.isEmpty()) {
            System.out.println(priorityQueue.poll());
        }
        
        // 堆栈示例 - 使用Deque
        Deque<Integer> stack = new ArrayDeque<>();
        stack.push(10);
        stack.push(20);
        stack.push(30);
        
        System.out.println("\n堆栈内容(LIFO):");
        while (!stack.isEmpty()) {
            System.out.println(stack.pop());
        }
        
        // Collections工具类示例
        List<Integer> nums = new ArrayList<>();
        nums.add(5);
        nums.add(2);
        nums.add(8);
        nums.add(1);
        
        Collections.sort(nums);
        System.out.println("\n排序后的列表: " + nums);
        
        Collections.reverse(nums);
        System.out.println("反转后的列表: " + nums);
        
        System.out.println("最大值: " + Collections.max(nums));
        System.out.println("最小值: " + Collections.min(nums));
    }
}

四、数组与集合使用对比

以下是数组和集合的使用场景、优势劣势及代码示例的完整表格:

数据结构 使用场景 优势 劣势 代码示例
数组 1. 数据量固定且已知(如月份天数、配置参数) 2. 需要高效随机访问(如图像处理像素数组) 3. 存储基本数据类型(如int[]char[] 1. 内存连续 ,访问效率高(时间复杂度O(1)) 2. 无额外开销 ,内存占用少 3. 直接支持基本类型,无需装箱/拆箱 1. 长度固定 ,无法动态扩展 2. 功能有限 ,缺乏排序、搜索等高级方法 3. 类型单一,所有元素必须相同类型 java // 声明并初始化整型数组 int[] numbers = {10, 20, 30}; // 访问元素 int first = numbers[0]; // 输出: 10 // 遍历数组 for (int i = 0; i < numbers.length; i++) { System.out.println(numbers[i]); }
集合(List) 1. 数据量动态变化(如用户列表、日志记录) 2. 需要频繁插入/删除元素(如任务队列) 3. 存储对象类型(如String、自定义类) 1. 动态扩容 ,无需预先指定大小 2. 功能丰富 ,提供add()remove()sort()等方法 3. 类型灵活,支持泛型(可存储不同类型对象) 1. 内存不连续 ,访问效率略低(如LinkedList需遍历) 2. 额外开销 ,需存储元数据(如容量、负载因子) 3. 仅支持对象 ,基本类型需自动装箱(如Integer java // 创建ArrayList并添加元素 List<String> names = new ArrayList<>(); names.add("Alice"); names.add("Bob"); // 访问元素 String firstName = names.get(0); // 输出: Alice // 遍历集合 for (String name : names) { System.out.println(name); } // 删除元素 names.remove("Bob");
集合(Set) 1. 需要去重(如标签系统、唯一ID集合) 2. 快速判断元素是否存在(如黑名单过滤) 1. 自动去重 ,无需手动检查 2. 查找效率高 (如HashSet基于哈希表实现) 1. 无序存储 ,无法通过索引访问 2. 功能受限 ,不支持get(index)等操作 java // 创建HashSet并添加元素 Set<String> tags = new HashSet<>(); tags.add("Java"); tags.add("Python"); tags.add("Java"); // 自动去重,集合大小为2 // 判断元素是否存在 boolean hasJava = tags.contains("Java"); // 输出: true
集合(Map) 1. 键值对存储(如字典、缓存系统) 2. 需要快速通过键查找值(如数据库索引) 1. 高效查找 (如HashMap时间复杂度O(1)) 2. 结构灵活,支持自定义键类型 1. 键唯一 ,重复键会覆盖值 2. 无序存储 (除非使用TreeMap java // 创建HashMap并添加键值对 Map<String, Integer> scores = new HashMap<>(); scores.put("Alice", 90); scores.put("Bob", 85); // 通过键获取值 int aliceScore = scores.get("Alice"); // 输出: 90 // 遍历键值对 for (Map.Entry<String, Integer> entry : scores.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); }

总结

通过本文的学习,我们掌握了Java中数组和集合的基本用法:

  1. 数组

    • 固定大小,类型相同,连续内存
    • 支持一维、二维及更高维度
    • 使用Arrays类进行排序、搜索、复制等操作
  2. 集合框架

    • List:有序可重复,常用实现有ArrayList和LinkedList
    • Set:无序不可重复,常用实现有HashSet和TreeSet
    • Map:键值对存储,常用实现有HashMap和TreeMap
    • Queue/Deque:队列和双端队列接口
    • 使用Collections工具类进行排序、反转等操作

数组和集合各有优缺点:

  • 数组简单高效,但大小固定
  • 集合大小可变,提供更多功能,但稍有性能开销

在实际开发中,应根据具体需求选择合适的数据结构。对于固定大小的数据,数组是更好的选择;对于需要动态增删的数据,集合更为合适。

相关推荐
想躺平的咸鱼干3 分钟前
Volatile解决指令重排和单例模式
java·开发语言·单例模式·线程·并发编程
Owen_Q21 分钟前
Denso Create Programming Contest 2025(AtCoder Beginner Contest 413)
开发语言·算法·职场和发展
hqxstudying30 分钟前
java依赖注入方法
java·spring·log4j·ioc·依赖
·云扬·38 分钟前
【Java源码阅读系列37】深度解读Java BufferedReader 源码
java·开发语言
liulilittle1 小时前
C++ i386/AMD64平台汇编指令对齐长度获取实现
c语言·开发语言·汇编·c++
巴里巴气1 小时前
selenium基础知识 和 模拟登录selenium版本
爬虫·python·selenium·爬虫模拟登录
19891 小时前
【零基础学AI】第26讲:循环神经网络(RNN)与LSTM - 文本生成
人工智能·python·rnn·神经网络·机器学习·tensorflow·lstm
JavaEdge在掘金2 小时前
Redis 数据倾斜?别慌!从成因到解决方案,一文帮你搞定
python
ansurfen2 小时前
我的第一个AI项目:从零搭建RAG知识库的踩坑之旅
python·llm
Bug退退退1232 小时前
RabbitMQ 高级特性之重试机制
java·分布式·spring·rabbitmq