Java集合框架详解

目录

引言

一、集合框架概述

1.1 什么是集合框架

1.2 集合框架的优点

二、集合框架的整体结构

2.1 集合框架的继承关系

三、核心接口详解

3.1 Collection接口

3.2 List接口

3.3 Set接口

3.4 Map接口

3.5 Queue接口

3.6 Deque接口

四、集合框架的实现类详解

4.1 ArrayList

4.2 LinkedList

4.3 HashSet

4.4 TreeSet

4.5 HashMap

4.6 TreeMap

4.7 PriorityQueue

五、集合框架的算法和工具类

5.1 Collections类

5.2 Arrays类

六、集合与泛型

七、集合的遍历方式

7.1 使用 Iterator

7.2 使用增强的 for 循环

7.3 使用 Stream API

八、线程安全的集合

8.1 同步集合

8.2 并发集合

九、集合的不可变性

9.1 不可变集合

9.2 Collections.unmodifiableXXX

十、集合的选择和性能考虑

10.1 选择合适的集合

10.2 性能考虑

十一、常见问题与注意事项

11.1 ConcurrentModificationException

11.2 HashMap的线程安全问题

11.3 equals 和 hashCode 方法

十二、总结

参考文献


引言

Java集合框架(Java Collections Framework)是Java提供的一套功能强大、结构完善的集合类库,用于存储和操作数据集合。它定义了一组接口和类,提供了常用的数据结构实现,如列表(List)、集合(Set)、映射(Map)和队列(Queue)等。通过使用集合框架,开发者可以大大提高编程效率,减少重复代码,并提高代码的可读性和可维护性。


一、集合框架概述

1.1 什么是集合框架

集合框架是一个统一的架构,用于表示和操作集合。它包含以下内容:

  • 接口(Interfaces): 表示集合的抽象数据类型,如 CollectionListSetMap 等。
  • 实现(Implementations): 具体的集合类,实现了集合接口,如 ArrayListHashSetHashMap 等。
  • 算法(Algorithms): 操作集合的通用方法,如排序、搜索等,由 Collections 类提供。

1.2 集合框架的优点

  • 一致性: 所有集合都遵循共同的接口规范,提供一致的编程模型。
  • 可重用性: 提供了常用数据结构的高效实现,避免重复造轮子。
  • 灵活性: 丰富的接口和实现类,满足各种数据存储和操作需求。
  • 性能优化: 经过优化的算法和数据结构,提高程序性能。

二、集合框架的整体结构

Java集合框架主要由以下几部分组成:

  • 核心接口: CollectionMap
  • 子接口: ListSetQueueDequeSortedSetSortedMap
  • 实现类: 各种集合类,如 ArrayListLinkedListHashSetTreeSetHashMapTreeMap
  • 工具类: Collections 类,提供集合操作的静态方法

2.1 集合框架的继承关系

下图展示了集合框架的主要接口和类的继承关系:

 

mathematica

复制代码

Iterable └── Collection ├── List ├── Set │ └── SortedSet └── Queue └── Deque Map └── SortedMap


三、核心接口详解

3.1 Collection接口

Collection 是最基本的集合接口,提供了对集合对象进行基本操作的方法。

主要方法:

  • boolean add(E e): 添加元素
  • boolean remove(Object o): 删除元素
  • boolean contains(Object o): 判断是否包含某元素
  • int size(): 返回集合大小
  • void clear(): 清空集合
  • Iterator<E> iterator(): 返回迭代器

3.2 List接口

List 接口继承自 Collection,表示有序的元素集合,允许重复元素。

常用实现类:

  • ArrayList: 基于动态数组,随机访问效率高
  • LinkedList: 基于双向链表,插入、删除效率高
  • Vector: 线程安全的动态数组(已不推荐使用)

主要方法:

  • void add(int index, E element): 在指定位置添加元素
  • E get(int index): 获取指定位置的元素
  • E set(int index, E element): 替换指定位置的元素
  • E remove(int index): 移除指定位置的元素
  • int indexOf(Object o): 返回元素的索引

示例代码:

 

java

复制代码

List<String> list = new ArrayList<>(); list.add("苹果"); list.add("香蕉"); list.add("橘子"); for (String fruit : list) { System.out.println(fruit); }

3.3 Set接口

Set 接口继承自 Collection,表示不包含重复元素的集合。

常用实现类:

  • HashSet: 基于哈希表,元素无序
  • LinkedHashSet: 保持元素插入顺序
  • TreeSet: 基于红黑树,元素有序

主要特性:

  • 不允许重复元素
  • 无序(除非使用有序实现类)

示例代码:

 

java

复制代码

Set<Integer> set = new HashSet<>(); set.add(1); set.add(2); set.add(2); // 重复元素,添加失败 for (Integer num : set) { System.out.println(num); }

3.4 Map接口

Map 接口不属于 Collection 体系,但在集合框架中占有重要地位,用于存储键值对映射。

常用实现类:

  • HashMap: 基于哈希表,无序
  • LinkedHashMap: 保持插入顺序
  • TreeMap: 基于红黑树,键有序
  • Hashtable: 线程安全的哈希表(已不推荐使用)

主要方法:

  • V put(K key, V value): 添加键值对
  • V get(Object key): 获取指定键的值
  • V remove(Object key): 移除指定键的键值对
  • boolean containsKey(Object key): 判断是否包含指定键
  • Set<K> keySet(): 获取所有键的集合
  • Collection<V> values(): 获取所有值的集合

示例代码:

 

java

复制代码

Map<String, Integer> map = new HashMap<>(); map.put("张三", 25); map.put("李四", 30); for (String name : map.keySet()) { System.out.println(name + "的年龄是" + map.get(name)); }

3.5 Queue接口

Queue 接口继承自 Collection,表示队列数据结构,遵循 FIFO(先进先出)原则。

常用实现类:

  • LinkedList: 也实现了 Queue 接口
  • PriorityQueue: 优先级队列,元素按自然顺序或指定比较器排序

主要方法:

  • boolean offer(E e): 添加元素到队列尾部
  • E poll(): 移除并返回队列头部的元素
  • E peek(): 返回队列头部的元素,但不移除

示例代码:

 

java

复制代码

Queue<String> queue = new LinkedList<>(); queue.offer("任务1"); queue.offer("任务2"); System.out.println(queue.poll()); // 输出:任务1 System.out.println(queue.peek()); // 输出:任务2

3.6 Deque接口

Deque(Double Ended Queue)接口继承自 Queue,表示双端队列,支持在两端添加和移除元素。

常用实现类:

  • LinkedList
  • ArrayDeque

主要方法:

  • void addFirst(E e): 在队列头部添加元素
  • void addLast(E e): 在队列尾部添加元素
  • E removeFirst(): 移除并返回队列头部的元素
  • E removeLast(): 移除并返回队列尾部的元素
  • E getFirst(): 返回队列头部的元素,但不移除
  • E getLast(): 返回队列尾部的元素,但不移除

示例代码:

 

java

复制代码

Deque<String> deque = new ArrayDeque<>(); deque.addFirst("头部元素"); deque.addLast("尾部元素"); System.out.println(deque.getFirst()); // 输出:头部元素 System.out.println(deque.getLast()); // 输出:尾部元素


四、集合框架的实现类详解

4.1 ArrayList

  • 特点: 基于动态数组,支持随机访问,查询效率高,插入和删除效率较低(除尾部操作)。
  • 适用场景: 需要频繁读取元素,较少插入和删除操作的场景。

示例代码:

 

java

复制代码

List<String> arrayList = new ArrayList<>(); arrayList.add("A"); arrayList.add("B"); arrayList.add("C");

4.2 LinkedList

  • 特点: 基于双向链表,插入和删除效率高(在任意位置),随机访问效率低。
  • 适用场景: 需要频繁插入和删除元素的场景。

示例代码:

 

java

复制代码

List<String> linkedList = new LinkedList<>(); linkedList.add("A"); linkedList.add("B"); linkedList.add("C");

4.3 HashSet

  • 特点: 基于哈希表实现,元素无序,不允许重复元素。
  • 底层实现: 通过 HashMap 实现,元素作为键,值为固定对象。

示例代码:

 

java

复制代码

Set<String> hashSet = new HashSet<>(); hashSet.add("A"); hashSet.add("B"); hashSet.add("A"); // 添加失败 for (String s : hashSet) { System.out.println(s); }

4.4 TreeSet

  • 特点: 基于红黑树实现,元素有序(按自然顺序或指定比较器),不允许重复元素。
  • 适用场景: 需要对元素进行排序的集合。

示例代码:

 

java

复制代码

Set<Integer> treeSet = new TreeSet<>(); treeSet.add(3); treeSet.add(1); treeSet.add(2); for (Integer num : treeSet) { System.out.println(num); // 输出:1 2 3 }

4.5 HashMap

  • 特点: 基于哈希表实现,存储键值对,键不可重复,值可重复,无序。
  • 底层实现: 数组 + 链表(JDK 1.8 以后引入红黑树优化)。

示例代码:

 

java

复制代码

Map<String, Integer> hashMap = new HashMap<>(); hashMap.put("A", 1); hashMap.put("B", 2); hashMap.put("A", 3); // 覆盖旧值 for (Map.Entry<String, Integer> entry : hashMap.entrySet()) { System.out.println(entry.getKey() + " = " + entry.getValue()); }

4.6 TreeMap

  • 特点: 基于红黑树实现,键有序(按自然顺序或指定比较器),键不可重复。
  • 适用场景: 需要按键排序的映射。

示例代码:

 

java

复制代码

Map<String, Integer> treeMap = new TreeMap<>(); treeMap.put("C", 3); treeMap.put("A", 1); treeMap.put("B", 2); for (String key : treeMap.keySet()) { System.out.println(key); // 输出:A B C }

4.7 PriorityQueue

  • 特点: 优先级队列,元素按优先级排序(自然顺序或指定比较器)。
  • 底层实现: 基于堆(通常是二叉堆)。

示例代码:

 

java

复制代码

Queue<Integer> priorityQueue = new PriorityQueue<>(); priorityQueue.offer(3); priorityQueue.offer(1); priorityQueue.offer(2); while (!priorityQueue.isEmpty()) { System.out.println(priorityQueue.poll()); // 输出:1 2 3 }


五、集合框架的算法和工具类

5.1 Collections类

Collections 类提供了一系列静态方法,用于操作集合,如排序、搜索、线程安全包装等。

常用方法:

  • sort(List<T> list): 对列表进行升序排序
  • reverse(List<?> list): 反转列表元素顺序
  • shuffle(List<?> list): 随机打乱列表元素
  • binarySearch(List<? extends Comparable<? super T>> list, T key): 二分查找
  • max(Collection<? extends T> coll): 返回集合中的最大元素
  • min(Collection<? extends T> coll): 返回集合中的最小元素
  • synchronizedList(List<T> list): 返回线程安全的列表

示例代码:

 

java

复制代码

List<Integer> nums = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5)); Collections.sort(nums); System.out.println(nums); // 输出:[1, 1, 3, 4, 5] Collections.shuffle(nums); System.out.println(nums); // 输出:随机顺序

5.2 Arrays类

Arrays 类提供了操作数组的静态方法,与集合操作类似。

常用方法:

  • asList(T... a): 将数组转换为 List
  • sort(Object[] a): 对数组进行排序
  • binarySearch(Object[] a, Object key): 在数组中进行二分查找
  • toString(Object[] a): 返回数组的字符串表示

示例代码:

 

java

复制代码

int[] array = {3, 1, 4, 1, 5}; Arrays.sort(array); System.out.println(Arrays.toString(array)); // 输出:[1, 1, 3, 4, 5]


六、集合与泛型

Java的集合框架广泛使用了泛型(Generics),使得集合能够存储特定类型的对象,增强了类型安全性,避免了类型转换的麻烦。

示例代码:

 

java

复制代码

List<String> stringList = new ArrayList<>(); stringList.add("Hello"); // stringList.add(123); // 编译错误,类型不匹配 String str = stringList.get(0); // 不需要强制类型转换


七、集合的遍历方式

7.1 使用 Iterator

Iterator 接口提供了遍历集合元素的方法,主要方法包括:

  • boolean hasNext(): 判断是否有下一个元素
  • E next(): 获取下一个元素
  • void remove(): 移除当前元素

示例代码:

 

java

复制代码

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C")); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); if ("B".equals(element)) { iterator.remove(); // 移除元素 } } System.out.println(list); // 输出:[A, C]

7.2 使用增强的 for 循环

增强的 for 循环(也称为 for-each 循环)简化了集合的遍历。

示例代码:

 

java

复制代码

for (String element : list) { System.out.println(element); }

7.3 使用 Stream API

Java 8 引入的 Stream API 提供了更强大的集合操作功能。

示例代码:

 

java

复制代码

list.stream() .filter(s -> s.startsWith("A")) .forEach(System.out::println);


八、线程安全的集合

8.1 同步集合

Collections 类提供了同步包装的方法,使集合变为线程安全。

示例代码:

 

java

复制代码

List<String> syncList = Collections.synchronizedList(new ArrayList<>()); syncList.add("A");

8.2 并发集合

Java 提供了专门的并发集合类,位于 java.util.concurrent 包中。

常用并发集合:

  • ConcurrentHashMap: 线程安全的哈希表
  • CopyOnWriteArrayList: 适用于读多写少的场景
  • BlockingQueue: 支持阻塞操作的队列,如 LinkedBlockingQueue

示例代码:

 

java

复制代码

Map<String, Integer> concurrentMap = new ConcurrentHashMap<>(); concurrentMap.put("A", 1); List<String> cowList = new CopyOnWriteArrayList<>(); cowList.add("A");


九、集合的不可变性

9.1 不可变集合

不可变集合是指一旦创建后,不能被修改的集合。Java 9 引入了创建不可变集合的便捷方法。

示例代码:

 

java

复制代码

List<String> immutableList = List.of("A", "B", "C"); // immutableList.add("D"); // UnsupportedOperationException

9.2 Collections.unmodifiableXXX

使用 Collections 类的 unmodifiableXXX 方法,将可变集合包装为不可变集合。

示例代码:

 

java

复制代码

List<String> modifiableList = new ArrayList<>(Arrays.asList("A", "B", "C")); List<String> unmodifiableList = Collections.unmodifiableList(modifiableList); // unmodifiableList.add("D"); // UnsupportedOperationException


十、集合的选择和性能考虑

10.1 选择合适的集合

根据需求选择合适的集合类型,可以提高程序性能和可维护性。

  • 需要快速随机访问: 使用 ArrayList
  • 需要频繁插入和删除: 使用 LinkedList
  • 需要保证线程安全: 使用并发集合,如 ConcurrentHashMap
  • 需要元素有序: 使用 TreeSetTreeMap
  • 需要不允许重复元素: 使用 Set

10.2 性能考虑

  • 时间复杂度: 了解集合操作的时间复杂度,如 ArrayList 的随机访问是 O(1),而 LinkedList 是 O(n)。
  • 空间复杂度: 不同的集合实现有不同的内存占用情况,需要根据实际情况选择。
  • 线程安全: 使用同步集合或并发集合,避免线程安全问题。

十一、常见问题与注意事项

11.1 ConcurrentModificationException

在使用迭代器遍历集合时,如果同时对集合进行修改,可能会抛出 ConcurrentModificationException

解决方法:

  • 使用迭代器的 remove 方法进行元素删除
  • 使用并发集合

11.2 HashMap的线程安全问题

HashMap 不是线程安全的,在多线程环境下可能会出现数据不一致的问题。

解决方法:

  • 使用 ConcurrentHashMap
  • 使用同步包装: Collections.synchronizedMap(new HashMap<>())

11.3 equals 和 hashCode 方法

在使用集合(如 HashSetHashMap)时,需要正确重写对象的 equalshashCode 方法,确保元素的唯一性和正确性。


十二、总结

Java集合框架提供了丰富而强大的数据结构和算法,实现了常用的集合接口和类,极大地方便了开发者进行数据的存储和操作。通过深入理解集合框架的各个接口和实现类,以及它们的特性和适用场景,开发者可以编写出高效、健壮的代码。

在实际开发中,应根据具体需求选择合适的集合类型,注意线程安全和性能问题,并遵循最佳实践,充分发挥集合框架的优势。


参考文献

  1. 《Java编程思想》(Thinking in Java),Bruce Eckel 著
  2. 《Effective Java》,Joshua Bloch 著
  3. Java官方文档https://docs.oracle.com/javase/8/docs/
  4. Java API文档Java Platform SE 8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值