一、集合和数组的区别
-
数组:
- 固定大小,存储类型一致。
- 支持随机访问。
- 不支持动态扩展。
-
集合:
- 大小可变,存储类型可以不同。
- 提供丰富的方法操作元素。
- 支持动态扩展。
二、Collection 集合的方法
add(E e)
:添加元素。remove(Object o)
:移除元素。size()
:获取集合大小。isEmpty()
:检查集合是否为空。contains(Object o)
:检查集合是否包含某个元素。iterator()
:返回迭代器。
三、常用集合的分类
1. Collection 接口(单列集合)
-
List 接口:元素按进入先后有序保存,可重复。
- LinkedList:链表实现,插入删除快,线程不安全。
- ArrayList:数组实现,随机访问快,线程不安全。
- Vector:数组实现,线程安全。
-
Set 接口:仅接收一次,不可重复。
- HashSet:使用哈希表存储元素。
- LinkedHashSet:维护插入顺序,基于 HashMap 实现,双向链表保持顺序。
- TreeSet:底层实现为二叉树,元素自动排序。
- HashSet:使用哈希表存储元素。
2. Map 接口(双列集合)
- Hashtable:线程安全。
- HashMap:线程不安全。
- LinkedHashMap:在 HashMap 基础上维护一条双向链表,有序的。
- WeakHashMap:使用弱引用。
- TreeMap:红黑树实现,自动排序。
- ConcurrentHashMap:
- JDK 1.7 之前:通过 Segment 数组结构和 HashEntry 数组结构实现。每个 Segment 加锁,支持最多 16 个并发线程。
- JDK 1.8 之后:通过 node 数组、链表和红黑树的数据结构实现,使用
synchronized
和 CAS(比较并交换)进行并发控制,红黑树情况使用 TreeNode。
四、List 和 Set 集合详解
1. List 和 Set 的区别
- List:有序、可重复。
- Set:无序、不可重复。
2. List 详解
- ArrayList:底层数组,查询快,增删慢,线程不安全。
- LinkedList:底层链表,增删快,查询慢,线程不安全。
- Vector:底层数组,线程安全,效率低。
3. Set 详解
- HashSet:无序且唯一,线程不安全。
- LinkedHashSet:保持元素插入顺序,线程不安全。
- TreeSet:自动排序,唯一性需重写
hashCode()
和equals()
方法。
4. List 和 Set 总结
- List:支持随机访问,元素有序。
- Set:不支持随机访问,元素无序且唯一。
五、Map 详解
- Map:保存键值对,键不可重复。
- HashMap:非线程安全,支持空键值。
- TreeMap:非线程安全,按自然顺序排序。
1. HashMap 和 Hashtable 的比较
- HashMap:非线程安全,允许空键值。
- Hashtable:线程安全,不允许空键值。
2. 线程安全与非线程安全集合类
- 非线程安全:LinkedList、ArrayList、HashSet、HashMap。
- 线程安全:Vector、Hashtable、ConcurrentHashMap。
六、适用场景分析
- ArrayList:适合频繁查询的场景。
- LinkedList:适合频繁插入和删除的场景。
- HashSet:适合快速查找,不需要排序的场景。
- TreeSet:适合需要排序的场景。
- HashMap:适合快速查找键值对的场景。
- TreeMap:适合需要排序的键值对场景。
- ConcurrentHashMap:适合高并发场景下的键值对存取。