一.Java集合
1.java常用的集合,区别
ArraryList:有序集合,以数组的方式存储, 插入涉及到元素的移动, 索引较快而插入较慢
LinkedList:(指针)底层是链表,新增删除比较快。
HashMap:底层是数组+链表(线程不安全), HashTable不能接受空键值对
HashTable:线程安全的Map,可以接受空的键值,
HashSet:无序集合
ConcurrentHashMap:线程安全的Map(分时段锁实现,效率比HashTable高)
2.hashMap实现原理
通过put get 来存取对象, put时调用 hashCode()方法 计算key的hashcode 找到bucket位置存储;
get时通过键对象的equals方法 找到正确的键值对
3.hashMap插入数据原理:见素材库
判断数组是否为空,为空进行初始化;
不为空,计算 k 的 hash 值,通过(n - 1) & hash计算应当存放在数组中的下标 index;
查看 table[index] 是否存在数据,没有数据就构造一个Node节点存放在 table[index] 中;
存在数据,说明发生了hash冲突(存在二个节点key的hash值一样), 继续判断key是否相等,相等,用新的value替换原数据(onlyIfAbsent为false);
如果不相等,判断当前节点类型是不是树型节点,如果是树型节点,创造树型节点插入红黑树中;(如果当前节点是树型节点证明当前已经是红黑树了)
如果不是树型节点,创建普通Node加入链表中;判断链表长度是否大于 8并且数组长度大于64, 大于的话链表转换为红黑树;
插入完成之后判断当前节点数是否大于阈值,如果大于开始扩容为原数组的二倍。
4.解决冲突解决办法
1.开放地址法
2.再hash法
3.链地址法----hashMap使用
4.建立一个公共溢出去
5.hashMap产生闭环的原因(1.7jdk会发生)
hashmap是线程不安全的集合,多线程访问时,就有可能在执行HashMap.get时进入死循环,将cpu的消耗到100%。
hashMap采用链表解决Hash冲突。因为是链表结构,很容易形成闭合的链路。这样在循环的时候对HashMap就行get操作就会产生死循环。
1.8jdk不会发生闭环
在 resize() 的最后一个 do-while,把原来的链表根据hash位置,重新拆成了2个链表,然后分别放到