Java集合简单理解
Java 的集合框架(Java Collections Framework, JCF)是 Java 中用于存储和操作数据结构的核心库,提供了丰富的接口和实现类,用于处理不同类型的集合数据。以下是详细的介绍:
一、集合框架的体系结构
Java 集合主要分为两大接口:
Collection
接口:存储单一元素。- 子接口:
List
(有序可重复)、Set
(无序不可重复)、Queue
(队列)。
- 子接口:
Map
接口:存储键值对(Key-Value)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L6KW4Q8y-1742140403056)(https://i.imgur.com/3V7gXQ6.png)]
二、Collection
接口及实现类
1. List
(有序、可重复)
- 特点:元素按插入顺序存储,允许重复。
- 常用实现类:
ArrayList
:- 基于动态数组实现,支持快速随机访问(通过索引)。
- 初始容量为 10,扩容时增长 50%(
newCapacity = oldCapacity + oldCapacity >> 1
)。 - 线程不安全,适用于读多写少的场景。
LinkedList
:- 基于双向链表实现,插入和删除效率高(时间复杂度 O(1))。
- 支持队列(
Queue
)和双端队列(Deque
)操作。
Vector
(已过时):- 线程安全的动态数组,所有方法用
synchronized
修饰,性能较差。 - 替代方案:使用
Collections.synchronizedList(new ArrayList<>())
或CopyOnWriteArrayList
(并发场景)。
- 线程安全的动态数组,所有方法用
2. Set
(无序、不可重复)
- 特点:元素唯一,不保证顺序。
- 常用实现类:
HashSet
:- 基于
HashMap
实现,元素存储在键的位置(值用PRESENT
对象占位)。 - 依赖
hashCode()
和equals()
保证唯一性。 - 时间复杂度:添加、删除、查询均为 O(1)。
- 基于
LinkedHashSet
:- 继承
HashSet
,内部通过链表维护插入顺序。 - 适合需要按插入顺序遍历的场景。
- 继承
TreeSet
:- 基于红黑树(
TreeMap
)实现,元素按自然顺序或自定义Comparator
排序。 - 时间复杂度:添加、删除、查询均为 O(log n)。
- 基于红黑树(
3. Queue
(队列)
- 特点:先进先出(FIFO)或优先级的元素处理。
- 常用实现类:
LinkedList
:可作为普通队列使用。PriorityQueue
:- 基于堆结构实现,元素按优先级排序。
- 自然顺序或通过
Comparator
定义顺序。
ArrayDeque
:- 基于循环数组实现的双端队列,适合高效的头尾操作。
三、Map
接口及实现类
- 特点:键值对存储,键唯一。
- 常用实现类:
HashMap
:- 基于数组+链表/红黑树(Java 8+),键的哈希值决定存储位置。
- 允许
null
键和null
值,线程不安全。 - 扩容机制:默认容量 16,负载因子 0.75(容量达到阈值时扩容为 2 倍)。
LinkedHashMap
:- 继承
HashMap
,通过链表维护插入顺序或访问顺序(LRU 缓存)。
- 继承
TreeMap
:- 基于红黑树实现,键按自然顺序或自定义
Comparator
排序。
- 基于红黑树实现,键按自然顺序或自定义
Hashtable
(已过时):- 线程安全的哈希表,被
ConcurrentHashMap
取代。
- 线程安全的哈希表,被
ConcurrentHashMap
:- 分段锁(Java 7)或 CAS + synchronized(Java 8+)实现高并发。
- 推荐替代
Hashtable
用于多线程场景。
四、工具类 Collections
提供对集合的常用操作:
- 排序:
Collections.sort(list)
- 线程安全包装:
Collections.synchronizedList(list)
- 不可变集合:
Collections.unmodifiableList(list)
- 查找极值:
Collections.max(collection)
五、迭代器 Iterator
- 作用:遍历集合元素。
fail-fast
机制:- 在遍历过程中检测到集合被修改(如
add
/remove
),立即抛出ConcurrentModificationException
。 - 适用于
ArrayList
、HashMap
等非线程安全集合。
- 在遍历过程中检测到集合被修改(如
fail-safe
机制:- 遍历时对原集合的修改不影响迭代器(如
ConcurrentHashMap
的迭代器)。
- 遍历时对原集合的修改不影响迭代器(如
六、Java 8+ 新特性
- Lambda 表达式与集合:
list.forEach(element -> System.out.println(element));
- Stream API:
list.stream().filter(e -> e > 5).map(e -> e * 2).collect(Collectors.toList());
HashMap
优化:- 当链表长度 ≥ 8 时转换为红黑树,提高查询效率。
七、如何选择集合类?
- 需要唯一性:
Set
(HashSet
、TreeSet
)。 - 需要有序性:
List
(ArrayList
、LinkedList
)。 - 键值对存储:
Map
(HashMap
、ConcurrentHashMap
)。 - 多线程环境:
ConcurrentHashMap
、CopyOnWriteArrayList
。 - 排序需求:
TreeSet
、TreeMap
。
八、示例代码
// List 示例
List<String> arrayList = new ArrayList<>();
arrayList.add("Java");
arrayList.add("Python");
// Set 示例
Set<Integer> hashSet = new HashSet<>();
hashSet.add(1);
hashSet.add(2);
// Map 示例
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Apple", 10);
hashMap.put("Banana", 20);
// 使用 Stream 过滤
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
通过理解集合框架的结构和特性,可以更高效地选择适合业务场景的数据结构。