关于“集合框架底层原理”的一些问题
问:Java 集合框架的主要接口有哪些?
答:Java 集合框架主要包括两个根接口:Collection
和 Map
。
- Collection 接口:用于存储单个元素,主要包括三个子接口:
- List:有序、可重复的集合。
- Set:无序、不可重复的集合。
- Queue:用于实现队列结构,支持先进先出(FIFO)等特性。
- Map 接口:用于存储键值对(key-value)映射关系。
问:ArrayList 的底层实现原理是什么?
答:ArrayList 是基于动态数组实现的集合,底层使用 Object[]
数组存储元素。默认初始容量为 10,当容量不足时,会扩容为原容量的 1.5 倍。它支持快速随机访问,时间复杂度为 O(1),但在中间插入或删除元素时,需要移动后续元素,时间复杂度为 O(n)。ArrayList 是非线程安全的。
问:LinkedList 的底层实现原理是什么?
答:LinkedList 是基于双向链表实现的集合,每个节点包含前驱和后继指针。它适合频繁的插入和删除操作,时间复杂度为 O(1),但随机访问效率较低,时间复杂度为 O(n)。LinkedList 实现了 Deque
接口,可作为双端队列使用,也是非线程安全的。
问:HashMap 的底层实现原理是什么?
答:HashMap 是基于哈希表实现的,底层使用数组加链表或红黑树的结构存储键值对。默认初始容量为 16,负载因子为 0.75。当链表长度超过 8 且数组长度大于 64 时,链表会转换为红黑树,以提高查找效率。HashMap 允许一个 null
键和多个 null
值,元素无序,非线程安全。
问:HashSet 的底层实现原理是什么?
答:HashSet 是基于 HashMap 实现的集合,底层使用 HashMap 存储元素。每个添加到 HashSet 的元素都会作为 HashMap 的键存储,值为一个固定的对象。HashSet 不允许存储重复元素,最多允许一个 null
元素,元素的顺序不保证,非线程安全。
问:TreeSet 的底层实现原理是什么?
答:TreeSet 是基于 TreeMap 实现的集合,底层使用红黑树(Red-Black Tree)存储元素。它可以自动对元素进行排序,默认按自然顺序排序,也可以通过构造函数传入比较器进行定制排序。TreeSet 不允许存储 null
元素,插入、删除、查找操作的时间复杂度为 O(log n),非线程安全。
问:ConcurrentHashMap 的底层实现原理是什么?
答:ConcurrentHashMap 是线程安全的哈希表实现。在 JDK 1.7 中,采用分段锁(Segment)机制,将整个表分为多个段,每个段独立加锁,提高并发性能。在 JDK 1.8 中,取消了分段锁,采用了 CAS(Compare-And-Swap)和 synchronized 关键字相结合的方式,使用数组加链表或红黑树的结构存储键值对,进一步提高了并发性能。ConcurrentHashMap 不允许 null
键或值。
问:ArrayList 和 LinkedList 有哪些区别?
答:
- 底层数据结构:ArrayList 基于动态数组实现,LinkedList 基于双向链表实现。
- 访问效率:ArrayList 支持快速随机访问,时间复杂度为 O(1);LinkedList 需要从头或尾遍历,时间复杂度为 O(n)。
- 插入和删除效率:ArrayList 在中间插入或删除元素时,需要移动后续元素,时间复杂度为 O(n);LinkedList 插入和删除操作效率较高,时间复杂度为 O(1)。
- 线程安全性:两者都不是线程安全的。
问:HashMap 和 Hashtable 有哪些区别?
答:
- 线程安全性:HashMap 是非线程安全的,Hashtable 是线程安全的,所有方法都被 synchronized 修饰。
- 性能:由于 Hashtable 的同步机制,性能较低;HashMap 性能较高。
- null 键和值:HashMap 允许一个
null
键和多个null
值;Hashtable 不允许null
键或值。 - 继承关系:HashMap 继承自 AbstractMap;Hashtable 继承自 Dictionary(已过时)。