集合面试题
1.Collection:
①List: Vector(Stack) , ArrayList , LinekdList
②Set: HashSet(LinkedHashSet) , TreeSet
③Queue: PriorityQueue , ArrayDeque , LinekdList
Map:
HashMap , TreeMap , HashTable(Properties)
2.Collection 和Collections 的区别?
Collection:
①是集合的顶级接口,定义了集合中统一的接口方法
②Collection接口有很多常用的实现类
③Collection的意义是为了具体的集合提供了最大化的统一操作方法
④其直接继承的接口有List和Set及Queue
Collections:
①集合的工具类
②提供了很多静态方法用于对集合元素进行排序,搜索及线程安全等操作
3.HashMap是线程安全的吗?如何得到一个线程安全的Map?
①HashMap线程不安全
②利用Collections工具类提供的synchronizedMap(map),利用装饰者设计模式,增强方法。
使用ConcurrentHashMap
HashTable
4.List和Set的区别?
①List
List:元素有序,可以通过索引获取元素,允许重复元素;底层通常是通过线性表(数组,链表)实现;
②Set
Set:元素无序,不可以通过索引获取元素,不允许重复;底层通常是通过二叉搜索树,hash表实现
5.HashMap 和Hashtable 的区别?
①Hashtable是线程安全的,HashMap线程不安全
②HashMap允许null键和null值,HashTable不允许
6.ArrayList和LinkedList的区别?
①ArrayList
ArrayList底层基于数组实现,采用动态扩容机制;
由于数组在内存中是连续的存储单元;所以在中间删除|插入元素比较慢;尾部却很快;
插入和删除的平均复杂度0(n)
根据索引查找的平均复杂度0(1)
②LinkedList
LinkedList底层基于双向非循环链表
由于双向链表可以从头部和尾部操作;所以在中间删除|插入元素比较慢;头部尾部比较快
插入和删除的平均复杂度0(n)
根据索引查找的平均复杂度0(n)
7.HashSet的实现原理
①、HashSet底层利用HashMap实现
②、HashSet中的元素存储在HashMap的key
③、HashMap的value统一采用: private static final Object PRESENT = new Object();
8.如何实现数组和List之间的转化
①、List转化为数组:toArray() T[]
②、数组转化为List:Arrays.asList(T...t) List<T>
9.ArrayList和Vector的区别
底层都是基于数组实现
①线程安全:
Vector是线程安全(synchronized)
ArrayList不是
如果需要一个线程安全的ArrayList,一般推荐CopyOnWriteArrayList
②扩容:
ArrayList扩容1.5倍
Vector默认扩容2倍
10.Queue中的peek()和poll()方法有什么区别
①peek()查看队列头部元素
②poll()出队
11.Iterator和ListIterator的区别
Iterator和ListIterator都是迭代器接口,不同的集合有不同的实现;ListIterator是Iterator的子接口
①Iterator可以遍历List也可以遍历Set,因为List和Set接口中都有:Iterator<E> iterator();
②ListIterator不能遍历Set,只有List接口中有:ListIterator<E> listIterator();
③Iterator只能向后遍历(hashNext,next),ListIterator不尽可以向后遍历,也可以向前遍历(hasPrevious,previous)
④Iterator中对集合元素的操作只有删除,ListIterator提供了获取前一个元素索引,后一个元素索引,添加元素,替换元素等方法
12.HashMap底层数据结构是什么?1.7和1.8有什么区别?
①1.7 数据结构:数组 + 链表
②1.8数据结构:数组 + 链表|红黑树
13.HashMap存储元素的流程
①、当使用put方法存储key value数据
②、首先会获取key的hashCode
③、对hashCode进行二次hash
④、对hash值取模数组的长度,得到数组索引(桶下标)
⑤、将key value存入到指定索引的链表或者红黑树中
为什么要采用这种存储方案;提高查找效率,时间复杂度可以达到0(1)
14.HashMap链表什么时候转化红黑树
转红黑条件 只有 当链表中的元素个数大于8 (此时 node有9个),并且数组的长度大于等于64时才会将链表转为红黑树
15.HashMap什么时候扩容
①capacity 即数组容量,默认16
②loadFactor 加载因子,默认是0.75
③threshold 阈值。阈值=容量*加载因子
④当hashMap中元素个数超过阈值,就会触发扩容,每次扩容一倍
16.HashMap桶中为什么不直接存放红黑树
①链表短的时候和红黑树性能差不多;
②红黑树一个节点占用的内存要比链表一个节点占用内存大(数据结构)
③如果hash值很随机,按照罗松分布,长度超过8的链表概率为 0.00000006
红黑树防止恶意DOS(Denial Of Service)攻击(伪造数据让数据的hashCode一样)
17.红黑树什么时候退化成链表
① 情况1:数组扩容,导致树的拆分,并且拆分后的节点<=6个
②情况2:红黑树元素被删除,如果根节点的左子树,右子树,左孙子,右孙子,有一个为null; 再次删除一个节点,退化成链表
18.索引如何计算
①.调用hashCode方法获取key的hashCode
②对hashCode再调用hashMap的hash方法进行二次hash运算 :hashCode ^ (hashCode >> 16)
③最后使用hash % 数组长度得到索引hash & (数组长度-1) ,注意:等价运算有个要求,数组长度必须是2的n次方
19.索引计算为何要进行二次hash的结果计算索引
将hash的分布更均匀
将添加的元素,更能平均的分配到hash表中;
不至于某些桶中元素过多;
20.HashMap数组长度为何是2的n次幂
①、计算索引的时候,可以不用取模运算,采用位运算提高效率
②、扩容的时候hash & 原始容量=0的时候留在源位置,否则新位置=原始位置+原始容量
21.HashMap1.7和1.8添加元素的区别
①1.8:
1.在第一次put的时候创建数组
2.计算索引
3.如果索引位置是null,创建Node(链表节点),存放到索引位置
4.如果索引位置不是null,如果是TreeNode,走红黑树添加的逻辑,如果是Node,走链表添加的逻辑,如果链表长度超过8,走树化逻辑
5.添加完毕后判断元素的个数是否超过阈值,如果超过阈值,进行数组扩容
②1.7:
元素采用头插入,元素的个数超过阈值并且没有空位置,进行数组扩容
22.扩容因子为何是0.75
①大于该值节省空间,但是链表长度可能会比较长
②小于该值,扩容比较频繁,占用内存空间较大
23.多线程下操作hashMap会引发什么问题
①1.8 数据丢失后面添加的数据将前面添加的数据覆盖;
24.HashMap为什么要求key重写hashCode和equals方法
①重写的目标
2个对象equals相同,hashCode一定相同,
2个对象hashCode相同,不一定equals相同,
②为什么
Map要求Key不能相同.
如何判断Key已经存在:
1.通过key的hash值计算桶索引,如果桶索引位置没有元素,key一定不存在.
2.判断添加的key是否和桶中元素key相同,添加key的hash和桶中元素hash是一样
一样(equals) 相同(存在). 不相同(不存在)
25.Integer,Double,Float,String这些类的hashCode是如何重写;
Integer中的hashCode()方法返回的直接就是,int类型的数字本身.
Double中的hashCode()计算Double.doubleToLongBits(adouble)得到一个long,再执行[2.3];
Float中的hashCode()当值喂NaN时一律返回0x7fc00000,其它值,返回Float的储存格式的二进制数,并转换为int类型的数字给予返回.
String中的hashCode()把当前每个字符的Unicode编号进行一定的计算,来返回一个int值,当hash的值为0时,hashlsZero的boolean的值为true,避免重复计算.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异