-
Collection 与 Map的区别?
Collection 存储单个值,该接口提供迭代器
Map存储键值对,没有提供迭代器
-
迭代器的分类?
Iterator和ListIterator
-
Iterator和ListIterator的区别?
Iterator:Collection接口下所有的实现类都能获取的迭代器,提供了删除元素的方法
ListIterator:List接口下所有的实现类才能获取的迭代器,提供了删除、添加、插入的方法,设置起始下标开始遍历,倒叙遍历
-
Iterator为什么不能使用list进行添加、删除、插入的操作? 因在迭代器中会判断外部操作数和内部操作数是否一致,不一致就会报错。
获取迭代器是为了遍历。如果外部操作数和内部操作数不一致,就意味着在迭代器循环时list操作了数据(添加、插入、删除),让list和迭代器的数据不同步,所以需要抛出异常,如果没有这一步的设计,可能会导致遍历出的数据有误
-
ArrayList底层数据结构是什么?
一维数组
-
ArrayList的扩容机制是什么?
新容量是原来的1.5倍
-
ArrayList数组的默认长度是多少?
是10
-
ArrayList数组的最大长度是多少?
Integer.MAX_VALUE-8
-
ArrayList数组的最大长度为什么是Integer.MAX_VALUE-8?-
减8是为了存储数组的头部信息
-
LinkedList的底层数据结构是什么?
双向链表
-
ArrayList 和 LinkedList的区别
LinkedList添加了removeFirst()、removeLast()
ArrayList数据结构是一维数组,LinkedList的数据结构是双向链表
添加 - 不扩容:ArrayList
添加 - 扩容:LinkedList
删除末尾:ArrayList
删除中间:LinkedList
查询:ArrayList
修改:ArrayList
平时使用ArrayList最多,因为需求中查询功能是最多的
-
HashSet为什么是无序的?
(HashSet底层由HashMap实现)
无序:存入顺序和取出顺序不一致,无序不代表随机
存入顺序:获取元素的hash值计算出在数组中的下标
取出顺序:遍历数组
-
LinkedHashSet为什么是无序的?
(LinkedHashSet extends HashSet)
(LinkedHashSet底层由LinkedHashMap实现)
添加元素:设置了上一个节点地址和下一个节点地址 遍历元素:获取到第一个添加的节点,然后向下找下一个节点
-
TreeSet底层数据结构?
二叉树
-
JDK1.7版本的HashMap底层数据结构是什么?
一维数组+单向链表
-
JDK1.7版本的HashMap存储元素的过程?
存储Key-Value对
1.获取Key的hash值
2.通过散列算法获取到数组的下标
3.判断下标上是否有元素
3.1没有-直接插入
3.2有 - 判断两个对象是否相同(hash、==、equals)
相同 - 不存入数据
不相同 - 插入数据(头插法)
-
HashMap的hash桶是什么?
单向链表
-
HashMap的数组默认大小是多少?
16
-
HashMap的数组长度为什么是2的幂? 因为计算元素在数组中的下标是:长度-1 & key的hash值
如果长度不是2的幂,长度-1就会导致2进制的某一位是0,从而导致计算出的下标散列不均匀,数组中的某个空间永远存不到数据
-
HashMap数组最大容量是多少?
1<<30
-
HashMap数组最大容量为什么是1<<30?
HashMap最大容量是int类型
1<<31超出了int类型的取值范围
-
HashMap的负载因子是多少?
0.75
-
HashMap的负载因子为什么是0.75?
负载因子是0.75因为取得了时间和空间的平衡
负载因子过小会导致数组只装一点点数据就扩容,浪费了空间,利用了时间
负载因子过大会导致数组装满就扩容,浪费了时间,利用了空间
-
HashMap何时扩容?
元素个数大于阈值并且插入数据的下标上有元素
-
HashMap的扩容机制?
是原来长度的2倍
-
什么叫做Hash回环/死循环?
在多线程的程序下,一个线程不断的添加数据导致HashMap扩容,一个线程不断的遍历数据,扩容时节点中的单向链表导致地址回环
多线程下使用HashMap如果出现Hash回环,是程序员应该背的锅,因为HashMap明确说明此集合不是线程安全的,多线程下应该使用ConcurrentHashMap
-
什么是hash碰撞?
key的hash值一样,计算出的下标也是一样的
-
HashMap中的hashSeed(hash种子数)的作用是什么?
两个String的hash值有可能相同,就会产生hash碰撞,降低效率
HashMap如果存入的是String,计算hash值是就会又hashseed参与,降低hash碰撞的概率
-
JDK1.7版本和JDK1.8版本的HashMap有什么区别?
JDK1.7:数组+链表,头插法
JDK1.8:数组+链表->数组+红黑树,尾插法,获取hash值时低16位^高16位,使得hash值更加散列
-
JDK1.8版本什么时候数组+链表转换为数组+红黑树
数组长度大于64,并且链表长度大于8会数组+链表转换为数组+红黑树
-
为什么JDK1.8版本的HashMap会设计数组+链表转换为数组+红黑树
链表查询效率低,红黑树查询效率高
-
JDK1.8版本HashMap链表为什么长度大于8会转换为红黑树
因为泊松分布(统计概率学)
-
HashMap存null数据的位置?
数组下标为0的位置
-
HashMap vs Hashtable vs ConcurrentHashMap
HashMap :线程不安全的,可以存nullKey
Hashtable :线程安全的,不可以存nullKey
ConcurrentHashMap:线程安全的,不可以存nullKey
-
Hashtable vs ConcurrentHashMap
Hashtable :方法上加锁,效率低
ConcurrentHashMapJDK1.7:分段式加锁
ConcurrentHashMapJDK1.8:局部加锁+CAS