在 Java 编程世界中,集合框架是处理数据集合的核心工具,它为我们提供了一系列高效、灵活的数据结构,帮助我们应对各种复杂的存储与操作需求。本文将带你系统性地学习 Java 集合体系,从接口到实现类,从基础用法到进阶技巧,让你彻底掌握这一核心知识点。
一、集合体系总览
Java 集合框架主要分为两大体系:Collection 体系 和Map 体系。
- Collection 体系 :以
Collection接口为根,强调 "单个元素" 的集合操作,包含List(有序可重复)、Set(无序不可重复)、Queue(队列,先进先出)三大分支。 - Map 体系 :以
Map接口为根,强调 "键值对(Key-Value)" 的映射关系,用于存储具有映射逻辑的数据。
二、Collection 集合体系深度解析
1. Collection 接口:集合的通用契约
Collection是所有单列集合的根接口,定义了集合的通用方法,如:
boolean add(E e):添加元素boolean remove(Object o):移除元素boolean contains(Object o):判断是否包含元素int size():获取元素个数Iterator<E> iterator():获取迭代器,用于遍历集合
这些方法是操作集合的基础,所有Collection的实现类都必须遵守这些契约。
2. List 接口:有序可重复的元素序列
List接口继承自Collection,特点是元素有序、可重复 ,且允许通过索引操作元素。常用实现类有ArrayList、LinkedList、Vector。
(1)ArrayList
- 底层实现:动态数组(数组扩容机制)。
- 核心特点:查询快(基于索引的随机访问)、增删慢(数组元素移动成本高)。
- 适用场景:读多写少的业务场景,如数据查询、列表展示。
示例代码:
java
List<String> arrayList = new ArrayList<>();
arrayList.add("Java");
arrayList.add("Python");
arrayList.add("Java"); // 允许重复
System.out.println(arrayList.get(0)); // 输出"Java"
(2)LinkedList
- 底层实现:双向链表。
- 核心特点:查询慢(需遍历链表)、增删快(只需修改节点引用)。
- 适用场景:写多读少的业务场景,如频繁插入、删除元素的队列、栈结构。
示例代码:
java
List<String> linkedList = new LinkedList<>();
linkedList.add("Spring");
linkedList.add("Spring Boot");
linkedList.remove(0); // 移除第一个元素
(3)Vector
- 底层实现:动态数组(线程安全版 ArrayList)。
- 核心特点:线程安全(方法加同步锁)、效率低。
- 适用场景 :多线程环境下的集合操作(但现在更推荐
Collections.synchronizedList或CopyOnWriteArrayList)。
3. Set 接口:无序不可重复的元素集合
Set接口继承自Collection,特点是元素无序、不可重复 (基于元素的equals()和hashCode()方法判断唯一性)。常用实现类有HashSet、LinkedHashSet、TreeSet。
(1)HashSet
- 底层实现 :哈希表(基于
HashMap,元素作为 Map 的 Key,Value 为固定对象)。 - 核心特点:无序、去重、查询效率高。
- 注意点 :元素需正确重写
equals()和hashCode()方法,否则去重逻辑会失效。
示例代码:
java
Set<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Apple"); // 重复元素会被过滤
System.out.println(hashSet.size()); // 输出2
(2)LinkedHashSet
- 底层实现 :哈希表 + 链表(基于
LinkedHashMap)。 - 核心特点:有序(插入顺序)、去重、查询效率高。
- 适用场景:需要保留插入顺序的去重场景。
(3)TreeSet
- 底层实现 :红黑树(基于
TreeMap)。 - 核心特点:有序(自然排序或自定义比较器排序)、去重。
- 适用场景:需要对元素排序的去重场景。
示例代码:
java
Set<Integer> treeSet = new TreeSet<>();
treeSet.add(3);
treeSet.add(1);
treeSet.add(2);
System.out.println(treeSet); // 输出[1, 2, 3],自动排序
4. Queue 队列接口:先进先出的数据结构
Queue是一种 "先进先出(FIFO)" 的集合,常用于任务排队、消息队列等场景。常用实现类有LinkedList(同时实现 List 和 Queue)、PriorityQueue(优先队列)。
示例代码(队列的入队、出队):
java
Queue<String> queue = new LinkedList<>();
queue.offer("Task1"); // 入队
queue.offer("Task2");
queue.offer("Task3");
System.out.println(queue.poll()); // 出队,输出"Task1"
5. 集合的遍历方式
遍历集合是日常开发的高频操作,Java 提供了多种遍历方式:
-
普通 for 循环 :仅适用于
List(通过索引访问)。javafor (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } -
增强 for 循环(foreach) :适用于所有
Collection集合,语法简洁。javafor (String elem : set) { System.out.println(elem); } -
迭代器遍历 :分为普通迭代器
Iterator和双向迭代器ListIterator(仅List支持)。javaIterator<String> iterator = collection.iterator(); while (iterator.hasNext()) { String elem = iterator.next(); System.out.println(elem); // 支持遍历中删除元素(避免并发修改异常) iterator.remove(); }
6. 集合中的泛型 <E>
泛型是 Java 的 "类型安全" 机制,用于限制集合中元素的类型,避免运行时类型转换异常。
示例代码:
java
// 泛型指定元素为String,编译期就会检查类型
List<String> genericList = new ArrayList<>();
genericList.add("Hello");
// genericList.add(123); // 编译报错,不允许添加非String类型
7. 可变参数
可变参数允许方法接收任意数量 的同类型参数,语法为类型... 参数名,在集合操作中常用于批量添加元素。
示例代码:
java
public static void addAll(List<String> list, String... elems) {
for (String elem : elems) {
list.add(elem);
}
}
// 调用
List<String> list = new ArrayList<>();
addAll(list, "a", "b", "c");
8. 数组工具类(Arrays)
java.util.Arrays提供了数组操作的工具方法,如数组转集合、数组排序、二分查找等。
示例代码:
java
String[] arr = {"a", "b", "c"};
// 数组转List(注意:返回的是不可变List,不能增删元素)
List<String> arrList = Arrays.asList(arr);
// 数组排序
int[] intArr = {3, 1, 2};
Arrays.sort(intArr);
9. 集合工具类(Collections)
java.util.Collections提供了集合操作的工具方法,如排序、查找、线程安全包装等。
示例代码:
java
List<Integer> list = new ArrayList<>();
list.add(3);
list.add(1);
list.add(2);
// 排序
Collections.sort(list);
System.out.println(list); // 输出[1, 2, 3]
// 线程安全包装
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
三、Map 集合体系深度解析
Map是 "键值对" 映射的集合,键(Key)唯一,值(Value)可重复。常用实现类有HashMap、TreeMap、Hashtable、LinkedHashMap。
1. Map 接口的核心方法
V put(K key, V value):添加键值对V get(Object key):根据键获取值boolean containsKey(Object key):判断是否包含键boolean containsValue(Object value):判断是否包含值Set<K> keySet():获取所有键的集合Collection<V> values():获取所有值的集合Set<Map.Entry<K, V>> entrySet():获取所有键值对的集合
2. HashMap
- 底层实现:哈希表(数组 + 链表 + 红黑树,JDK8 及以后)。
- 核心特点:无序、键唯一、效率高(查询、增删均为 O (1) 级别)。
- 注意点 :默认初始容量 16,负载因子 0.75,扩容时容量翻倍;键为
null时会被存到索引 0 的位置。
示例代码:
java
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Java", 100);
hashMap.put("Python", 90);
hashMap.put("Java", 95); // 键重复,值会覆盖
System.out.println(hashMap.get("Java")); // 输出95
3. TreeMap
- 底层实现:红黑树。
- 核心特点:有序(键的自然排序或自定义比较器排序)、键唯一。
- 适用场景:需要对键排序的映射场景。
示例代码:
java
Map<Integer, String> treeMap = new TreeMap<>();
treeMap.put(3, "C");
treeMap.put(1, "A");
treeMap.put(2, "B");
System.out.println(treeMap); // 输出{1=A, 2=B, 3=C},按键排序
4. Hashtable
- 底层实现:哈希表(线程安全版 HashMap)。
- 核心特点 :线程安全(方法加同步锁)、效率低、键和值都不允许为
null。 - 适用场景 :古老的多线程场景(现在更推荐
ConcurrentHashMap)。
5. LinkedHashMap
- 底层实现:哈希表 + 链表。
- 核心特点:有序(插入顺序或访问顺序)、键唯一、效率高。
- 适用场景:需要保留插入 / 访问顺序的映射场景,如 LRU 缓存(基于访问顺序)。
四、集合体系的选择策略
在实际开发中,如何选择合适的集合?可以参考以下策略:
| 需求场景 | 推荐集合 |
|---|---|
| 有序可重复,随机访问 | ArrayList |
| 有序可重复,频繁增删 | LinkedList |
| 无序不可重复,效率优先 | HashSet |
| 无序不可重复,需插入顺序 | LinkedHashSet |
| 无序不可重复,需排序 | TreeSet |
| 键值对映射,效率优先 | HashMap |
| 键值对映射,需键排序 | TreeMap |
| 键值对映射,需插入顺序 | LinkedHashMap |
五、总结
Java 集合体系是 Java 编程的核心基石之一,掌握Collection和Map的各类实现类的特性、用法和适用场景,能让你在数据处理场景中如鱼得水。从ArrayList的数组高效查询,到LinkedList的链表灵活增删;从HashMap的哈希表极速映射,到TreeMap的红黑树有序排列,每一种集合都有其独特价值。