集合平时用的比较多的有哪些?
这个就是详细说下结合
Conllection 下 有arrayList 和 LinkList
Set下 是HasnSet
Map hanshMap 线程安全的话 是ConcurrenHashMap
1、List
ArrayList 和 LinkList 适用于什么场景
arrayList底层实现是一个数组,初始化的时候默认大小是0,新增的时候默认是10,扩容是原来的1.5倍,适用于查询场景;因为他是根据自己的下标进行查询。
linkList是基于双向链表的实现,带有头结点还有尾节点的,适用于一些插入、删除频繁的操作,查询会比较慢;因为linkLIst是来链表,查询的时候需要一个一个的去查询;
vector是线程安全的、基于数组,实现方法上都有synchronized。
linkLIst和arrarList哪一个查询慢?
linkList 是链表,他是从第一个开始一个一个比较
arrayList 查询是根据脚标查询
线程安全的情况下使用list
使用Voctor 他的每一个方法都是被synchronized修饰的
2、Map
hashMap是map类型的数据结构,底部实现是数组+链表 (1.8之后 数组+链表/红黑树)线程不安全,key可以为null
hashTable 是线程安全的 key不允许为空
ConcurrentHashMap 是线程安全的并发的情况下 使用这个因为hashTable是全程加锁的,性能不好
hashMap的结构和底层实现原理
hashMap底部是数组+链表的形式,1.8之后是数组+链表或者红黑树的形式
链表与红黑树的转换是 链表长度大于8 之后 并且hash桶大于64的时候就转成红黑树、红黑树节点小于等于6的时候会重新转成链表
hashMap扩容
hashMap的长度 * 负载因子 0.75 假设长度是100 那么在76的时候就进行扩容;扩容先创建一个新的Entry数组,长度是原来的2倍;再遍历原来的Entry数组,把所有的Entry重新hash劲新的数组。
hash桶默认是16个,有一个负载因子是0.75,hash桶默认是16 0.75x16=12,当他的hash桶的占用容量大于12的时候就会触发扩容,会扩容之前的两倍,或者是2的n次幂,把之前的那些元素在进行一次hash运算,然后添加到新的hash桶里面,按照链表或者红黑树的方式进行排列
为什么在达到8 之后是红黑树
jdk8之前是数组+ 链表实现的,查询的时间复杂度为on,链表过长的话遍历次数就会增加,这个时候效率就会变低,所以要用红黑树解决,他其实就是解决链表的查询问题
hash冲突
hashMap是不是线程安全的
不是,在1.7的时候put有一个resize的过程因为是头插容易造成环形链表导致死循环;1.8的时候多线程会有数据覆盖的可能
线程安全的使用hashTable 或者是ConcurrentHashMap
hashTable 效率低 因为对数据操作都加锁了;
ConcurrentHashMap
1.7的时候是一个分片数组,保证线程安全有一个Segment锁 集 成了 集成于 ReentrantLock 保证线程安全
1.8的时候改成hashMap数组+链表 使用Synchronized和CAS