枫叶の博客
友情链接
往期整理
  •   历史归档
  •   文章分类
  •   文章标签
Maple
文章
5
分类
1
标签
3
友情链接
往期整理
历史归档
文章分类
文章标签
Coding
Java 集合框架详解
发布于: 2025-1-1
最后更新: 2025-1-4
次查看
Java
type
status
date
slug
summary
tags
category
icon
password
在Java编程中,集合框架(Collections Framework)是一个用于存储和操作一组对象的统一架构。它提供了多种数据结构和算法,使得开发者能够高效地管理数据。本文将详细介绍Java集合框架的各个方面,适合作为学习笔记。

1. 集合的基本概念

  • *集合(Collection)**是一个接口,代表一组对象的集合。Java集合框架提供了各种接口和类,用于存储、检索和操作数据。集合框架的设计目标是提供统一的编程接口,支持不同类型的数据结构和算法。

为什么使用集合?

  • 动态大小:与数组不同,集合的大小是可变的,可以根据需要自动调整。
  • 丰富的操作:集合框架提供了丰富的方法用于添加、删除、查找、排序等操作。
  • 泛型支持:集合可以使用泛型来确保类型安全,减少类型转换错误。
  • 多样的实现:不同的集合实现适用于不同的场景,如快速访问、快速插入删除等。

2. 集合框架的接口层次结构

Java集合框架的接口层次结构如下图所示:

2.1 Collection接口

Collection是Java集合框架的根接口,定义了一组基本操作,如添加、删除、遍历等。所有的集合类(除了Map)都直接或间接地实现了Collection接口。

2.2 List接口

List接口表示一个有序的集合,允许存储重复的元素。常用的实现类包括ArrayList、LinkedList和Vector。
特点:
  • 有序:元素按插入顺序排列,可以通过索引访问。
  • 允许重复:同一个元素可以出现多次。

2.3 Set接口

Set接口表示一个不包含重复元素的集合。常用的实现类包括HashSet、LinkedHashSet和TreeSet。
特点:
  • 无序或有序:部分实现如TreeSet是有序的,HashSet则是无序的。
  • 不允许重复:集合中不允许存在重复的元素。

2.4 Queue接口

Queue接口表示一个先进先出(FIFO)的队列,适用于存储等待处理的元素。常用的实现类包括LinkedList和PriorityQueue。
特点:
  • 有序:元素按插入顺序排列。
  • 允许重复:可以包含相同的元素。
  • 特定操作:支持插入、删除、查看队首元素等操作。

2.5 Map接口

Map接口表示一个键值对的集合,键唯一但值可以重复。Map不是Collection的子接口,但属于集合框架的一部分。常用的实现类包括HashMap、LinkedHashMap和TreeMap。
特点:
  • 键唯一:每个键对应一个值,键不能重复。
  • 允许值重复:不同键可以映射到相同的值。
  • 快速查找:根据键快速查找对应的值。

3. 常用集合类

3.1 ArrayList

ArrayList是List接口的一个动态数组实现,支持快速随机访问,但在中间插入或删除元素时效率较低。
特点:
  • 动态数组:内部使用数组存储元素,自动调整大小。
  • 快速访问:通过索引访问元素的时间复杂度为O(1)。
  • 线程不安全:在多线程环境下需要手动同步。
使用场景:
  • 需要频繁随机访问元素。
  • 元素主要在末尾添加或删除。

3.2 LinkedList

LinkedList是List和Deque接口的实现,内部使用双向链表结构,适合频繁插入和删除操作。
特点:
  • 双向链表:每个元素包含对前后元素的引用。
  • 插入和删除高效:在任意位置插入或删除元素的时间复杂度为O(1)。
  • 随机访问慢:通过索引访问元素需要遍历链表,时间复杂度为O(n)。
使用场景:
  • 需要频繁在列表中间插入或删除元素。
  • 作为队列或双端队列使用。

3.3 HashSet

HashSet是Set接口的一个实现,基于哈希表,保证元素唯一但不保证顺序。
特点:
  • 哈希表:内部使用哈希表存储元素,保证查找、插入和删除的时间复杂度为O(1)。
  • 不保证顺序:元素的顺序不固定。
  • 允许null元素:可以存储一个null元素。
使用场景:
  • 需要存储不重复的元素,并且不关心顺序。
  • 快速查找元素是否存在。

3.4 TreeSet

TreeSet是Set接口的一个实现,基于红黑树,保证元素有序。
特点:
  • 红黑树:内部使用红黑树存储元素,保证元素有序,插入、删除和查找的时间复杂度为O(log n)。
  • 有序:元素按照自然顺序或指定的比较器顺序排列。
  • 不允许null元素:尝试添加null元素会抛出NullPointerException。
使用场景:
  • 需要存储不重复且有序的元素。
  • 需要范围查询或排序操作。

3.5 HashMap

HashMap是Map接口的一个实现,基于哈希表,存储键值对,键唯一。
特点:
  • 哈希表:内部使用哈希表存储键值对,保证查找、插入和删除的时间复杂度为O(1)。
  • 不保证顺序:键值对的顺序不固定。
  • 允许null键和null值:可以存储一个null键和多个null值。
使用场景:
  • 需要根据键快速查找对应的值。
  • 不关心键值对的顺序。

3.6 TreeMap

TreeMap是Map接口的一个实现,基于红黑树,存储键值对,键有序。
特点:
  • 红黑树:内部使用红黑树存储键值对,保证键有序,插入、删除和查找的时间复杂度为O(log n)。
  • 有序:键按照自然顺序或指定的比较器顺序排列。
  • 不允许null键:尝试添加null键会抛出NullPointerException,但允许null值。
使用场景:
  • 需要存储键值对且键有序。
  • 需要范围查询或排序操作。

4. 集合的泛型

  • *泛型(Generics)**允许在集合中指定元素的类型,确保类型安全,避免运行时的类型转换错误。
语法:
示例:
优点:
  • 类型安全:在编译时检查类型,避免类型转换错误。
  • 消除强制类型转换:无需在取出元素时进行类型转换。
  • 代码更清晰:明确集合中存储的元素类型。
通配符:
  • ?:表示未知类型。
  • ? extends Type:表示Type及其子类。
  • ? super Type:表示Type及其父类。
示例:

5. 集合的迭代与遍历

遍历集合是操作集合中的元素的常见方式。Java提供了多种遍历集合的方法。

5.1 Iterator迭代器

Iterator是集合框架提供的一种通用的遍历方式,适用于所有实现了Collection接口的集合。
使用方法:
示例:
注意事项:
  • 使用Iterator的remove()方法可以在遍历过程中删除元素,避免ConcurrentModificationException。
  • 在遍历时不应修改集合(如添加或删除元素),否则可能导致ConcurrentModificationException。

5.2 增强for循环

增强for循环(也称为for-each循环)是遍历集合的简洁方式,适用于所有实现了Iterable接口的集合。
语法:
示例:
优点:
  • 代码简洁,易读性高。
  • 不需要显式使用迭代器。
缺点:
  • 无法在遍历过程中删除元素。
  • 无法获取当前元素的索引。

5.3 Java 8 Streams API

Java 8引入的Streams API提供了声明性的方法来处理集合中的元素,支持并行操作和函数式编程风格。
使用方法:
示例:
优点:
  • 支持链式操作,代码简洁。
  • 内置并行处理,提升性能。
  • 支持复杂的数据处理,如过滤、映射、聚合等。
注意事项:
  • Streams是一次性的,遍历后不能重用。
  • 操作中不应修改源集合,避免副作用。

6. 集合的线程安全

在多线程环境下,集合的线程安全性是一个重要考虑因素。Java提供了多种方式来确保集合的线程安全。

6.1 同步集合

通过同步包装器将非线程安全的集合包装成线程安全的集合。
使用方法:
示例:
注意事项:
  • 同步集合的每个方法都是同步的,但复合操作(如遍历)仍需手动同步。
  • 手动同步示例:

6.2 并发集合

Java提供了专为并发设计的集合类,具备更高的性能和更细粒度的同步机制。
常用的并发集合:
  • ConcurrentHashMap:线程安全的哈希映射,支持高并发的读写操作。
  • CopyOnWriteArrayList:线程安全的动态数组,适用于读多写少的场景。
  • BlockingQueue及其实现类(如LinkedBlockingQueue、PriorityBlockingQueue):支持阻塞操作的队列,适用于生产者-消费者模型。
示例:
优点:
  • 更高的并发性能,适合多线程环境。
  • 内部采用更细粒度的锁或无锁算法,减少锁竞争。
使用场景:
  • 高并发的读写操作,如Web服务器中的请求处理。
  • 需要阻塞操作的队列,如任务调度和线程池。

7. 集合的常用方法

Java集合框架提供了丰富的方法用于操作集合中的元素。以下是一些常用的方法:

Collection接口常用方法

  • 添加元素:
    • boolean add(E e):添加一个元素。
    • boolean addAll(Collection<? extends E> c):添加一个集合中的所有元素。
  • 删除元素:
    • boolean remove(Object o):移除一个指定元素。
    • boolean removeAll(Collection<?> c):移除集合中包含的所有元素。
    • boolean retainAll(Collection<?> c):保留集合中包含的所有元素,移除不包含的元素。
  • 查询元素:
    • boolean contains(Object o):判断是否包含指定元素。
    • boolean containsAll(Collection<?> c):判断是否包含指定集合中的所有元素。
  • 集合大小:
    • int size():返回集合中的元素数量。
    • boolean isEmpty():判断集合是否为空。
  • 清空集合:
    • void clear():移除集合中的所有元素。
  • 转换为数组:
    • Object[] toArray():将集合转换为一个数组。
    • <T> T[] toArray(T[] a):将集合转换为指定类型的数组。

List接口常用方法

  • 按索引操作:
    • E get(int index):获取指定索引的元素。
    • E set(int index, E element):设置指定索引的元素。
    • void add(int index, E element):在指定索引处添加元素。
    • E remove(int index):移除指定索引的元素。
  • 搜索:
    • int indexOf(Object o):返回元素首次出现的索引。
    • int lastIndexOf(Object o):返回元素最后一次出现的索引。
  • 子列表:
    • List<E> subList(int fromIndex, int toIndex):返回列表的一个子视图。

Set接口常用方法

  • 无序或有序:根据具体实现类,Set可能是无序的(如HashSet)或有序的(如TreeSet)。

Map接口常用方法

  • 添加键值对:
    • V put(K key, V value):添加或更新一个键值对。
    • void putAll(Map<? extends K, ? extends V> m):添加一个映射中的所有键值对。
  • 删除键值对:
    • V remove(Object key):移除指定键的键值对。
    • void clear():移除所有键值对。
  • 查询键值对:
    • V get(Object key):根据键获取对应的值。
    • boolean containsKey(Object key):判断是否包含指定键。
    • boolean containsValue(Object value):判断是否包含指定值。
  • 键和值的集合视图:
    • Set<K> keySet():返回所有键的集合视图。
    • Collection<V> values():返回所有值的集合视图。
    • Set<Map.Entry<K, V>> entrySet():返回所有键值对的集合视图。

8. 集合的最佳实践

为了高效和安全地使用Java集合,遵循以下最佳实践是非常重要的。

8.1 选择合适的集合类型

根据具体需求选择合适的集合类型:
  • 快速随机访问:使用ArrayList。
  • 频繁插入删除:使用LinkedList。
  • 唯一性要求:使用HashSet或TreeSet。
  • 键值对存储:使用HashMap或TreeMap。
  • 并发操作:使用并发集合如ConcurrentHashMap。

8.2 使用泛型提高类型安全

始终使用泛型来定义集合,避免使用原始类型(如List而不是List<Object>)。
示例:

8.3 避免不必要的同步

尽量使用非同步的集合,除非确实需要线程安全。使用并发集合代替同步包装器,提升性能。

8.4 使用接口类型定义变量

使用接口类型(如List、Set)来定义集合变量,增加代码的灵活性。
示例:

8.5 优化集合的初始容量

根据预期的元素数量,合理设置集合的初始容量,减少扩容操作,提高性能。
示例:

8.6 使用不可变集合

在需要确保集合不被修改的场景,使用不可变集合,增强代码的安全性。
Java 9及以上:

8.7 避免在集合中存储null

尽量避免在集合中存储null,尤其是在键值对集合中,以防止NullPointerException和逻辑错误。

8.8 使用Stream API进行复杂操作

利用Java 8的Streams API进行过滤、映射、排序等复杂操作,提升代码的简洁性和可读性。
示例:

9. 示例代码

以下示例展示了集合框架的各个方面,包括添加、删除、遍历、使用泛型和并发集合。
输出示例:
解释:
  1. List示例:展示了ArrayList允许重复元素。
  1. Set示例:展示了HashSet不允许重复元素。
  1. Map示例:展示了HashMap根据键更新值。
  1. 遍历:使用增强for循环、Iterator和Streams API遍历集合。
  1. 并发集合:使用ConcurrentHashMap在多线程环境下安全地修改集合。

10. 总结

Java集合框架是Java编程中不可或缺的一部分,提供了多种数据结构和算法,满足不同的存储和操作需求。通过理解集合的基本概念、接口层次结构、常用集合类及其特性,开发者可以高效地选择和使用合适的集合类型。此外,掌握集合的泛型、迭代遍历、线程安全和最佳实践,有助于编写高效、健壮和可维护的代码。随着Java 8及其后续版本引入的Streams API和并发集合,Java集合框架的功能和性能得到了进一步的提升,使得数据处理更加简洁和高效。
  • 作者:Maple
  • 链接:https://mapleleaf.space/Coding/Java/Collection
  • 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章
Java多线程详解
Java概述
ChatBox调用APIJava多线程详解
Loading...
目录
0%
1. 集合的基本概念为什么使用集合?2. 集合框架的接口层次结构2.1 Collection接口2.2 List接口2.3 Set接口2.4 Queue接口2.5 Map接口3. 常用集合类3.1 ArrayList3.2 LinkedList3.3 HashSet3.4 TreeSet3.5 HashMap3.6 TreeMap4. 集合的泛型5. 集合的迭代与遍历5.1 Iterator迭代器5.2 增强for循环5.3 Java 8 Streams API6. 集合的线程安全6.1 同步集合6.2 并发集合7. 集合的常用方法Collection接口常用方法List接口常用方法Set接口常用方法Map接口常用方法8. 集合的最佳实践8.1 选择合适的集合类型8.2 使用泛型提高类型安全8.3 避免不必要的同步8.4 使用接口类型定义变量8.5 优化集合的初始容量8.6 使用不可变集合8.7 避免在集合中存储null8.8 使用Stream API进行复杂操作9. 示例代码10. 总结
Maple
Maple
你也想做游戏嘛?
文章
5
分类
1
标签
3
最新发布
Java概述
Java概述
2025-1-4
ChatBox调用API
ChatBox调用API
2025-1-4
DSCode
DSCode
2025-1-4
Java多线程详解
Java多线程详解
2025-1-4
Java 集合框架详解
Java 集合框架详解
2025-1-4
公告
-- 学无止境 ---
目录
0%
1. 集合的基本概念为什么使用集合?2. 集合框架的接口层次结构2.1 Collection接口2.2 List接口2.3 Set接口2.4 Queue接口2.5 Map接口3. 常用集合类3.1 ArrayList3.2 LinkedList3.3 HashSet3.4 TreeSet3.5 HashMap3.6 TreeMap4. 集合的泛型5. 集合的迭代与遍历5.1 Iterator迭代器5.2 增强for循环5.3 Java 8 Streams API6. 集合的线程安全6.1 同步集合6.2 并发集合7. 集合的常用方法Collection接口常用方法List接口常用方法Set接口常用方法Map接口常用方法8. 集合的最佳实践8.1 选择合适的集合类型8.2 使用泛型提高类型安全8.3 避免不必要的同步8.4 使用接口类型定义变量8.5 优化集合的初始容量8.6 使用不可变集合8.7 避免在集合中存储null8.8 使用Stream API进行复杂操作9. 示例代码10. 总结
2024.11.10-2025Maple.

枫叶の博客 | 你也想做游戏嘛?

Powered byNotionNext 4.7.7.