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 接口?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值