集合线程安全指的是集合本身操作put get是线程安全的,concurrent Hashmap能保证多线程put安全,但不能保证逻辑上两个线程先后get 和 put数据覆盖,数据的稳定安全;

Collection类

1. ArrayList

基本特性

  • 初始容量10
  • 扩容1.5倍,懒加载机制,第一次put才创建;


2. LinkedList

  • 可以添加任意元素
  • 线程不安全,没有实现同步

3.Vector[安全]

map类

1. HashMap

基本特性

  • 初始容量16
  • 负载因子0.75:扩容阈值(容量*因子)
  • 懒加载机制,第一次put才创建
  • 表长过8,且元素长度过64改红黑树
  • 不安全:两个线程同时操控同一个下标的哈希桶导致数据覆盖

jdk7和jdk8区别

jdk7采用的是头插法,采用的是数组 + 链表,节点叫entry

jdk8采用的优化的插入方法,采用数组 + 链表/ 红黑树,节点叫Node


2. HashTable[安全]

  • 线程安全:在get和set方法上面都加了锁;
  • 效率低:两个线程存储哈希桶位置不同,并发执行不影响结果,但也会被锁住依次执行;

3. ConcurrentHashMap[安全]

  • 分段锁 segment数组对象将哈希桶隔离开,线程安全效率高
  • 先哈希找到segment数组下标,锁住该片段,此时其他片段可以并发执行,再去segment对象里面的哈希数组进行哈希找到哈希桶操作。
  • 初始化时设定容量阈值和hashmap类似,但多一个并发度 ==> segment数组长度。segment长度固定,假设初始容量16.,并发度8,那么每个segment里面有2个长度的哈希桶,并且扩容是只扩容该segment对象里面的。
  • 构造函数(容量,并发度);根据并发度求出大于它的幂次方数(9 -> 16;17 -> 32)作为segment长度,其次容量/segment长度向上取整再找幂次方数 作为每个segment里面的Entry长度(最小默认2)。就构建完了。因为每次算hash与上下标2的次方数-1 可以快速的映射在长度区间内;


Java集合知识点整理_MySql

4. HashSet

  • 继承自hashmap,数组 + 链表/红黑树
  • 不可重复,将值存key,value不存值,存入重复对象时先哈希后找到下标,然后遍历链表上找key是否相等再插入,相等则覆盖,value空覆盖空。
  • 表长过8,且元素长度过64改红黑树

案例:添加一个用户类,如果姓名和年龄相同则认为是相同的不加入HashSet如何处理

答案:重写用户类 equls和hashCode();对比是先对比hashcode再对比对象equels。所以hashCode重写为Objects.hash(name,age),然后equels重写,如果姓名学号相等则返回true就行了。同一个名字加入set,首先判断hash相等,再检测到又相同的equels就退出;如果只重写equels就可能导致对象不同,hash不同就存的位子不一样就对比不到,所以要两个都重写就行;


5. LinkedHashSet

  • 继承自hashSet
  • 添加前后链表保证输入和输出的一致性