Java集合常见面试题总结

主要参考:JavaGuide小林coding,同时加上网上搜索整理和个人理解总结

1 集合概述

1.1 Java 集合概览🔥

Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 Collection 接口,主要用于存放单一元素;另一个是 Map 接口,主要用于存放键值对。对于 Collection 接口,下面又有三个主要的子接口:ListSetQueue

Java 集合框架如下图所示:

Java 集合框架概览

  • List :存储的元素是有序的、可重复的。常用的实现List的类有LinkedList,ArrayList
  • Set :存储的元素不可重复的。常用的实现有HashSet,LinkedHashSet和TreeSet。
  • Queue :按特定的排队规则来确定先后顺序,存储的元素是有序的、可重复的。常用的实现有 PriorityQueue.
  • Map :使用键值对(key-value)存储,key 是无序的、不可重复的,value 是无序的、可重复的。主要实现有TreeMap、HashMap、LinkedHashMap、ConcurrentHashMap。

1.2 数组与集合区别

  • 数组是固定长度的数据结构,一旦创建长度就无法改变,而集合是动态长度的数据结构,可以根据需要动态增加或减少元素。
  • 数组可以包含基本数据类型和对象,而集合只能包含对象。
  • 数组可以直接访问元素,而集合需要通过迭代器或其他方法访问元素。

2 List

2.1 ArrayList底层实现原理🔥

  • 底层数据结构:ArrayList底层是用动态的数组实现的
  • 初始容量:ArrayList初始容量为0,当第一次添加数据的时候才会初始化容量为10
  • 扩容逻辑:ArrayList在进行扩容的时候是原来容量的1.5倍,每次扩容都需要拷贝数组
  • 添加逻辑
    • 确保数组已使用长度(size)加1之后足够存下下一个数据
    • 计算数组的容量,如果当前数组已使用长度+1后的大于当前的数组长度,则调用grow方法扩容(原来的1.5倍)
    • 确保新增的数据有地方存储之后,则将新元素添加到位于size的位置上。
    • 返回添加成功布尔值。

添加数据的流程如下

image-20230427192644244

2.2 如何实现数组和List之间的转换

  • 数组转List ,使用JDK中java.util.Arrays工具类的asList方法
  • List转数组,使用List的toArray方法。无参toArray方法返回 Object数组,传入初始化长度的数组对象,返回该对象数组
List<String> myList = Arrays.asList(myArray); // 数组转list
str=myList.toArray(new String[0]); // list转数组

继续追问:用Arrays.asList转List后,如果修改了数组内容,list受影响吗?List用toArray转数组后,如果修改了List内容,数组受影响吗?

  • Arrays.asList转换list之后,如果修改了数组的内容,list会受影响,因为它的底层使用的Arrays类中的一个内部类ArrayList来构造的集合,在这个集合的构造器中,把我们传入的这个集合进行了包装而已,最终指向的都是同一个内存地址
  • list用了toArray转数组后,如果修改了list内容,数组不会影响,当调用了toArray以后,在底层是它是进行了数组的拷贝,跟原来的元素就没啥关系了,所以即使list修改了以后,数组也不受影响

2.3 ArrayList 与 LinkedList 区别?🔥

视频讲解:常见集合篇-08-ArrayList和LinkedList的区别是什么?_哔哩哔哩_bilibili

  • 底层数据结构: ArrayList 底层使用的是动态数组;LinkedList 底层使用的是 双向链表
  • 插入和删除效率不同: ArrayList在尾部的插入和删除操作效率较高,但在中间或开头的插入和删除操作效率较低,需要移动元素。LinkedList在任意位置的插入和删除操作效率都比较高,因为只需要调整节点之间的指针。
  • 随机访问的效率不同:ArrayList支持通过索引进行快速随机访问,时间复杂度为O(1)。LinkedList需要从头或尾开始遍历链表,时间复杂度为O(n)。
  • 空间占用: ArrayList 在创建时需要分配一段连续的内存空间,列表的结尾会预留一定的容量空间。而 LinkedList 的每个节点不光需要存储元素还要存储指针。
  • 使用场景: ArrayList适用于频繁随机访问和尾部的插入删除操作,而LinkedList适用于频繁的中间插入删除操作和不需要随机访问的场景。
  • 是否保证线程安全: ArrayListLinkedList 都不是线程安全的;

2.4 把ArrayList变成线程安全有哪些方法?

  • 使用Collections类的synchronizedList方法将ArrayList包装成线程安全的List:
  • 使用CopyOnWriteArrayList类代替ArrayList,它是一个线程安全的List实现:
  • 使用Vector类代替ArrayList,Vector是线程安全的List实现:

2.5 ArrayList list=new ArrayList(10)中的 list 扩容几次

在 ArrayList 的源码中提供了一个带参数的构造方法,这个参数就是指定的集合初始长度,所以给了一个10的参数,就是指定了集合的初始长度是10,这里面并没有扩容。

2.6 ArrayList 可以添加 null 值吗?

ArrayList 中可以存储任何类型的对象,包括 null 值。不过,不建议向 ArrayList 中添加 null 值, null 值无意义,会让代码难以维护比如忘记做判空处理就会导致空指针异常。

2.7 LinkedList 为什么不能实现 RandomAccess 接口?

Ra

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值