Java面试八股文(2023最新)--Java集合面试题

目录

1. 什么是集合

2. 集合和数组的区别

3. 集合框架的好处

4. 常用的集合类有哪些?

5. List, Set, Map三者区别

​编辑

6. HashMap和Hashtable有什么区别?

7. 如何决定使用HashMap还是TreeMap?

8. 说一下HashMap实现原理

9. 说一下HashSet的实现原理

10. ArrayList和LinkedList的区别是什么

11. 如何实现数组和List之间转换?

12. ArrayList和Vector的区别是什么?

13. Array和ArrayList有何区别?

14. 在Queue中poll()和remove()有什么区别?

15. 哪些集合类是线程安全的?

16. 集合底层的数据结构总结

17. ConcurrentHashMap和HashTable的区别


1. 什么是集合

  • 集合就是一个存放数据的容器,准确来说是放数据对象应用的容器
  • 集合类存放的是对象的引用,而不是对象的本身
  • 集合类型主要有三种: set(集),list(列表),map(映射)

2. 集合和数组的区别

  • 数组是固定长度,集合是可变长度的
  • 数组可以存放基本数据类型,也可以存放引用数据类型,集合只能存放引用数据类型
  • 数组存储的元素必须是同一个数据类型,集合存储的对象可以是不同的数据类型

3. 集合框架的好处

  • 容量自增长
  • 提供了高性能的数据结构和算法,使编码更轻松,提高了程序的速度和质量
  • 可以方便的扩展和改写集合,提高代码复用性,可操作性
  • 通过使用JDK自带的集合类,可以降低代码的维护和学习性API的成本

4. 常用的集合类有哪些?

  • map接口和controller接口是所有集合框架的父接口
    • controller接口的子接口包括: set接口和list接口
    • map接口的实现类主要有: HashMap, TreeMap, HashTable, ConcurrentHashMap以及Properties等
    • Set接口的实现类主要有: HashSet, TreeSet, LinkedHashSet等
    • List接口的实现类主要有: ArrayList, LinkedLisk, Stack , Vector等

5. List, Set, Map三者区别

  •  Java容器分为Controller和Map两大类,Controller集合的子接口有Set, List, Queue三种子接口.我们比较常用的是Set, List, Map接口不是Controller的子接口
  • Controller集合主要有List和Set两大接口
    • List: 一个有序容器(元素存入集合的顺序和取出的顺序一致), 元素可以重复,可以插入多个null元素,元素都有索引. 常用的实现类有ArrayList, LinkedList, Vector
    • Set: 一个无序容器(存入和取出顺序可能不一致), 不可以存储重复元素, 只允许存放一个null元素,必须保证元素唯一性.set接口常用实现类是: HashSet, LinkedHashSet以及TreeSet
    • Map是一个键值对,存储键,值之间的映射.key无序,唯一;value不要求有序,允许重复.map没有继承于Controller接口,从Map集合中检索元素时,只要给出键对象,就会返回对应值对象;常用实现类:HashMap, TreeMap, HashTable, LinkedHashMap, ConcurrentHashMap

6. HashMap和Hashtable有什么区别?

  • 存储: HashMap运行key和value可以为null , HashTable不允许
  • 线程安全: HashTable是线程安全的, HashMap非线程安全
  • 推荐使用: 在Hashtable的类注释可以看到, Hashtable是保留类不建议使用,推荐单线程的环境使用HashMap替代,如果需要多线程使用则用ConcurrentHashMap替代

7. 如何决定使用HashMap还是TreeMap?

  • 对于Map中插入,删除,定位一个元素这类操作, HashMap是最好的选择,因为相对而言HashMap的插入更快,但是你要对key集合进行有序的遍历,那么TreeMap是更好的选择

8. 说一下HashMap实现原理

  • HashMap基于Hash算法实现, 我们通过put(key,value)存储,通过get(key)获取.当传入key时,HashMap会根据key,hashCode()计算出hash值,根据hash值将value保存在bucket中,当计算出hash值相同时,我们称之为hash冲突,HashMap的做法是用链表+红黑树存储相同hash值的value.当hash冲突的个数比较少时,使用链表,比较多时 使用红黑树.

9. 说一下HashSet的实现原理

  • HashSet是基于HashMap实现的, HashSet底层使用HashMap保存所有元素,因此HashSet的实现比较简单,相关HashSet操作,基本上都是直接调用底层Hash Map的相关方法完成,但是HashSet不允许重复值.

10. ArrayList和LinkedList的区别是什么

  • 数据结构实现: ArrayList是动态数组的数据结构实现,而LinkedList是双向链表的数据结构实现
  • 随机访问效率: ArrayList比LinkedList在随机访问的时候效率要高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后的依次查找.
  • 增删效率: 在非首尾增删操作时,LinkedList比ArrayList效率高,因为ArrayList增删操作影响数组内其他数据下标.
  • 总结: 需要在频繁二点读取集合的元素时, 推荐ArrayList,而插入和删除操作较多,推荐LinkedList

11. 如何实现数组和List之间转换?

数组转List: 使用Array.asList(array)进行转换

List转数组: 使用List自带的toArray()方法

12. ArrayList和Vector的区别是什么?

  • 线程安全: Vector使用了Synchronized实现线程同步,是线程安全的, 而ArrayList是非线程安全的
  • 性能: ArrayList性能上优于Vector
  • 扩容: ArrayList和Vctor都会根据实际的需要动态调整容量, 只不过在Vector扩容每次增加一倍,而ArrayList只会增加50%

13. Array和ArrayList有何区别?

  • Array可以存储基本数据类型,ArrayList只能存储对象
  • Array固定大小,ArrayList大小是自动扩展
  • Array内置方法没有ArrayList多

14. 在Queue中poll()和remove()有什么区别?

  • 相同点:都是返回第一个元素,并在队列中删除返回的对象
  • 不同点:如果没有元素poll()会返回null,而remove()会直接抛出异常

15. 哪些集合类是线程安全的?

  • 线程安全:Vector,Hashtable,Stack
  • 线程不安全:HashMap
  • 注意:JDK1.5以后随着Java.util.concurrent并发包出现,他们也有自己对应的线程安全类,比如HashMap对应线程安全类是ConcurrentHashMap

16. 集合底层的数据结构总结

  • List
    • ArrayList : Object[] 数组
    • Vector:Object[] 数组
    • LinkedList:双向链表(jdk1.6之前是循环链表,jdk1.7取消了循环链表)
  • Set
    • HashSet(无序,唯一):基于HashMap实现,底层采用HashMap保存元素
    • LinkedHashSet:LinkedHashSet是HashSet子类,内部通过LinkedHashMap实现,类似LinkedHashMap内部是基于HashMap实现一样。
    • TreeSet(有序,唯一):红黑树(自平衡的排序二叉树)
  • Queue
    • ArrayQueue:Object[] 数组+双指针
    • PriorityQueue:数组实现二叉堆
  • Map
    • HashMap:JDK1.8之前HashMap由数组+链表组成,数组是HashMap的主体,链表则是为了解决Hash冲突的问题,Jdk8以后解决hash冲突有了较大变化,当链表长度大于阈值(默认为8)(将链表转换成红黑树前会判断,如果当前数组长度小于64,那么选择数组扩容,而不是转换成红黑树)时,将链表转换为红黑树,减少搜索时间
    • LinkedHashMap:LinkedHashMap继承HashMap,底层仍然是基于拉链式散列结构,即数组和链表或红黑树组成。另外LinkedHashMap在上面结构的基础上,增加了双向链表,使上面的结构可以保持键值对的插入顺序。同时通过对链表进行相关操作,实现了访问顺序相关逻辑。
    • Hashtable:数组+链表组成,数组是Hashtable的主体,链表则是主要解决hash冲突问题
    • TreeMap:红黑树

17. ConcurrentHashMap和HashTable的区别

  • 底层数据结构:
    • ConcurrentHashMap:JDK1.7采用分段数组+链表,JDK1.8数组+链表/红黑二叉树
    • HashTable:和JDK1.8以前的HashMap底层类似,都采用数组+链表,数组是HashMap主体,链表为了解决hash冲突
  • 线程安全
    • ConcurrentHashMap:
      • JDK1.7,ConcurrentHashMap对整个桶数组进行分割分段(分段锁),每把锁只锁容器中的部分数据,多线程访问容器不同数据段数据,不会出现锁竞争,提高了并发访问效率
      • JDK1.8,ConcurrentHashMap摒弃JDK1.7的概念,而是直接Node数组+链表+红黑树的数据结构实现,并发控制使用synchronized和CAS操作。整体看起来就是优化过且线程安全的HashMap
    • Hashtable(同一把锁):使用synchronized保证线程安全,效率非常低。一个线程访问同步方法,其他线程也访问同步方法,可能会进入阻塞或轮询的状态,例如使用put添加元素,另一个线程不能使用put,也不能使用get
  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月月崽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值