常见JAVA集合面试题(自用整理,持续更新)

一、简要介绍 Java 集合框架的整体架构

        1.Java 集合框架主要分为两大接口体系:Collection 和 Map

        2.Collection 是单列集合的根接口,下面又有三个子接口,分别是 List(有序、可重复)、Set(无序、不可重复)和 Queue(队列)。

        3.Map 是双列集合的根接口,用于存储键值对。

        4.以下是java集合的基础架构图

         5.Java 集合框架的核心继承关系图(文本描述版)

 
  1. ├─ Collection 接口(单列集合的根接口)

  2. │ ├─ List 接口(有序、可重复)

  3. │ │ ├─ ArrayList(动态数组实现,非线程安全)

  4. │ │ ├─ LinkedList(双向链表实现,非线程安全)

  5. │ │ └─ Vector(动态数组实现,线程安全,已过时)

  6. │ │ └─ Stack(继承自 Vector,后进先出栈结构)

  7. │ ├─ Set 接口(无序、不可重复)

  8. │ │ ├─ HashSet(基于哈希表,非线程安全)

  9. │ │ │ └─ LinkedHashSet(HashSet + 链表维护插入顺序)

  10. │ │ └─ TreeSet(基于红黑树,支持排序)

  11. │ └─ Queue 接口(队列,FIFO 原则)

  12. │ ├─ PriorityQueue(优先级队列,基于堆结构)

  13. │ └─ Deque 接口(双端队列)

  14. │ └─ LinkedList(实现 Deque)

  15. └─ Map 接口(双列集合,键值对存储)

  16. ├─ HashMap(基于哈希表,非线程安全)

  17. │ └─ LinkedHashMap(HashMap + 链表维护顺序)

  18. ├─ TreeMap(基于红黑树,支持键排序)

  19. └─ Hashtable(线程安全,已过时,不允许 null 键值)

  20. └─ Properties(继承自 Hashtable,用于配置文件)

 二、Collection 和 Collections 有什么区别?

        Collection是Java集合框架中的(顶层)接口,表示一组对象的集合。它定义了集合的基本行为,如添加、删除、遍历等操作。

        Collections是一个工具类,提供了一系列静态方法来操作各种集合对象,包括对集合排序、查找最大最小值、反转、随机化等操作。它并不是一个集合接口或类,而是一组方法的集合,用于方便对集合进行操作。

        以下是对Collection和Collections的一些代码使用介绍

 
 
  1. import java.util.ArrayList;

  2. import java.util.Collections;

  3. import java.util.Collection;

  4. public class CollectionExample {

  5. public static void main(String[] args) {

  6. // 创建一个ArrayList集合

  7. Collection<String> list = new ArrayList<>();

  8. // 向集合中添加元素

  9. list.add("Apple");

  10. list.add("Banana");

  11. list.add("Orange");

  12. // 使用Collections工具类对集合进行操作

  13. System.out.println("原始集合:" + list);

  14. // 使用Collections工具类进行排序

  15. Collections.sort((List<String>) list);

  16. System.out.println("排序后的集合:" + list);

  17. // 使用Collections工具类进行反转

  18. Collections.reverse((List<String>) list);

  19. System.out.println("反转后的集合:" + list);

  20. }

  21. }

AI写代码java运行

篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记【点击此处即可】免费获取

 三、List、Set和Map之间的区别是什么?

        List是有序集合,可以包含重复元素。

        Set是无序集合,不允许重复元素。

        Map是键值对的集合,每个键唯一对应一个值,键和值都可以是任意对象。

四、List的子类有哪些?它们之间有什么区别?

  • ArrayList、LinkedList、Vector是List的子类。
  • ArrayList是基于动态数组实现的,适合随机访问和遍历。
  • LinkedList是基于链表实现的,插入和删除操作效率高。
  • Vector是线程安全的动态数组,通常不推荐使用,可以使用ArrayList代替。

五、 Set的子类有哪些?它们之间有什么区别?

  • HashSet、TreeSet、LinkedHashSet是Set的子类。
  • HashSet是基于哈希表实现的,无序且不允许重复元素。
  • TreeSet是基于红黑树实现的,元素有序且不允许重复,支持自然排序和定制排序。
  • LinkedHashSet是基于哈希表和链表实现的,具有插入顺序。

六、 Queue的常见实现类有哪些?它们之间有什么区别?

  • LinkedList、PriorityQueue是Queue的常见实现类。
  • LinkedList可以作为队列和栈来使用,实现了Queue和Deque接口。
  • PriorityQueue是优先级队列,根据元素的自然顺序或自定义比较器排序。

七、 Map的常见实现类有哪些?它们之间有什么区别?

  • HashMap、TreeMap、LinkedHashMap是Map的常见实现类。
  • HashMap基于哈希表实现,无序且允许键和值为null。
  • TreeMap基于红黑树实现,键有序且不允许键为null,支持自然排序和定制排序。
  • LinkedHashMap基于哈希表和双向链表实现,保持插入顺序或访问顺序。

八、常用集合线程安全总结表格

接口实现类线程安全替代方案特点适用场景
ListArrayList非线程安全Collections.synchronizedList()
CopyOnWriteArrayList
动态数组,查询快、增删慢,允许null元素单线程环境下的快速访问
LinkedList非线程安全Collections.synchronizedList()
CopyOnWriteArrayList
双向链表,增删快、查询慢,允许null元素频繁增删的单线程场景
Vector线程安全(过时)CopyOnWriteArrayList动态数组,线程安全,性能低,已被Collections.synchronizedList()替代遗留代码兼容
Stack线程安全(过时)使用Deque实现(如 ArrayDeque)继承自 Vector,后进先出(LIFO)结构栈结构需求,但推荐使用Deque
SetHashSet非线程安全Collections.synchronizedSet()
ConcurrentHashSet
基于哈希表,无序且不可重复,允许null元素单线程下快速查找和去重
TreeSet非线程安全Collections.synchronizedSortedSet()
ConcurrentSkipListSet
基于红黑树,有序且不可重复,不允许null元素单线程下需要排序的场景
LinkedHashSet非线程安全无直接替代,需手动同步维护插入顺序,基于哈希表 + 链表需要有序且去重的单线程场景
MapHashMap非线程安全Collections.synchronizedMap()
ConcurrentHashMap
基于哈希表,键唯一,允许null键值单线程下快速键值对操作
TreeMap非线程安全Collections.synchronizedSortedMap()
ConcurrentSkipListMap
基于红黑树,键有序,不允许null单线程下需要键排序的场景
Hashtable线程安全(过时)ConcurrentHashMap线程安全,不允许null键值,性能低,已被ConcurrentHashMap替代遗留代码兼容
LinkedHashMap非线程安全无直接替代,需手动同步维护插入顺序或访问顺序,适合缓存场景需要有序键值对的单线程场景

 九、ArrayList 和 LinkedList 的区别?

       关键点

  • 数据结构ArrayList是动态数组,LinkedList是双向链表。
  • 增删性能LinkedList头尾操作快,ArrayList中间操作慢。
  • 查询性能ArrayList通过索引直接访问,查询快。

         扩展

        ArrayList默认容量为 10,扩容为原容量的 1.5 倍。

十、HashMap 的底层结构? 

        关键点

  • JDK 1.7:数组 + 链表。
  • JDK 1.8:数组 + 链表 + 红黑树(链表长度≥8 且容量≥64 时转换)。

        扩展 

  • 扩容触发条件:当前元素数量超过loadFactor(默认 0.75)× 容量。
  • 扩容为 2 倍,需重新计算哈希值并迁移数据。

 篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记【点击此处即可】免费获取

十一、HashSet 和 TreeSet 的区别? 

        关键点

  • HashSet基于哈希表,无序;TreeSet基于红黑树,有序。
  • TreeSet不允许null元素,HashSet允许。

十二、HashMap 和 Hashtable 的区别? 

        关键点

  • Hashtable线程安全(synchronized),不允许null键值;HashMap非线程安全,允许null键值。
  • ConcurrentHashMap替代Hashtable,性能更高。

十三、ConcurrentHashMap 的实现原理? 

        关键点

  • JDK 1.7:分段锁(Segment),每个Segment独立加锁。
  • JDK 1.8:CAS+synchronized,锁粒度细化到节点。

        扩展 

ConcurrentHashMap支持高并发,吞吐量远高于Hashtable

十四、说说Vector 和 ArrayList 的区别? 

  • Vector线程安全(synchronized),扩容为原容量的 2 倍;
  • ArrayList非线程安全,扩容为 1.5 倍。

十五、说说什么是hash冲突,并说说如何解决hash冲突

         (PS:如何回答此面试题,说说鄙人之见)

        1.定义hash冲突

        哈希冲突是指不同的键经过哈希函数计算后得到相同的哈希值,导致它们被分配到哈希表的同一个桶中。

        概念很长,可能不太好理解,可以借着以下的话来辅助理解:

        哈希冲突就好比是在分配房间号的时候,不同的人由于名字相同(键经过哈希函数计算后得到相同的哈希值),导致他们被分配到了同一个房间(哈希表的同一个桶)里面。

        2. 列举解决hash冲突的方法

        常见hash冲突解决方法总结,如下表格

方法原理典型应用场景优缺点
链地址法(Separate Chaining)将同一桶中的元素用链表或红黑树存储,冲突时追加到链表尾部或树中。Java 的HashMapHashSet(JDK 1.8 后链表长度超过 8 转为红黑树)。优点:实现简单,冲突处理高效;
缺点:链表过长时查询性能下降。
开放定址法(Open Addressing)冲突时在哈希表中寻找下一个可用位置(通过探测序列)。Java 的ThreadLocal.ThreadLocalMap优点:节省空间,无需额外存储结构;
缺点:可能导致 “二次聚集”,影响性能。
再哈希法(Rehashing)冲突时使用不同的哈希函数重新计算哈希值,直到找到可用桶。部分数据库索引优化场景。优点:减少哈希冲突概率;
缺点:多次计算哈希值增加开销。
建立公共溢出区所有冲突元素统一存储在另一个溢出区,主哈希表只存储非冲突元素。早期哈希表实现(如 C 语言中的某些库)。优点:结构简单;
缺点:溢出区访问效率低,维护复杂。
扩容(Resizing)当哈希表负载因子超过阈值时,扩容哈希表并重新分配元素(即 “再哈希”)。Java 的HashMap(默认负载因子 0.75)。优点:降低冲突概率,提升整体性能;
缺点:扩容操作耗时,需权衡扩容阈值。

        3.结合具体场景举例

        HashSet 和 HashMap 使用链地址法存储冲突元素。当链表长度超过 8 时,会转换为红黑树以提升查询效率。此外,HashMap 的扩容机制会动态调整哈希表大小,减少冲突的发生。

         4.解决哈希冲突的核心

        选择高效的冲突处理策略和合理的哈希表参数(如负载因子),以平衡空间和时间复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值