JDK1.7哈希碰撞是采用(头插)法来改变节点的排列 可能出现收尾想连的问题(也叫环形链表) 采用数组加链表
JDKC1.8哈希碰撞是采用(尾查)发来改变节点的排列 尾插法不会影响原有的顺序 采用数组加链表加红黑树
HashMap扩容的效率影响很大 建议在初始化时将hashmap的大小设置好
Hash表又称为散列表
HashMap冲突解决 JDK1.8当中使用
HashMap如果传入key值为null那么将hash值设置为0存储
在HashMap中存放自定义的键时,就需要重写自定义对象的hashcode和equals方法 在使用对象当key值时我们如果重写hashcode和equals方法那么此对象new多少对象都可以获取相同的值
好比一个Value值多个Key获取同一个Value 如果不重写hashcode和equals方法那么每次new对象当Key获取的全部都是不同的Value值
ConcurrentHashMap与HashMap的区别
ConcurrentHashMap是线程安全的 在JDK1.7当中他锁的粒度较大锁的是(segment)
1.1 在JDK1.8当中锁是数组当中的某一个节点
1.2 引入了红黑树来降低时间复杂度 红黑树的时间复杂度为 o(`log n`)
1.3 ConcurrentHashMap引入了并发扩容的一个实现 多个线程对原始数组进行分片处理 提升了扩容过程中的迁移的效率
1.4 ConcurrentHashMap有个size()方法获取总元素个数 在多线程并发编程当中为了保证数据的原子性的前提下实现个数的累加 性能很低
ConcurrentHashMap在竞争不激烈的时候使用CAS 如果竞争激烈的情况使用数组来维护元素个数如果增加元素个数的时候直接随机从数组当中选择一个加CAS进行递增操作
引入数据对并发更新的一个负载
HashTable
默认容量为11 不要求底层数组的容量一定是2的整数幂,扩容是将容量变为原来的2倍+1
如果传入null值 直接调用HashCode方法计算Hash值 所以不能传入null值
ConcurrentHashMap底层为并发分片扩容那为什么HashTable底层不是使用并行分片扩容?
因为ConcurrentHashMap引入了分割(segmentation),不论它变得多么大,仅仅需要锁定map的某个部分,
而其它的线程不需要等到迭代完成才能访问map。简而言之,在迭代的过程中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map。
HashMap为什么使用红黑树作为扩容? (将节点设置为红色在插入时对红黑树造成的影响是小的,而黑色是最大的 )
红黑树也是一种平衡二叉树,每个节点有一个储存位表示节点的颜色,可以是红色或者黑色。通过对任意一条从根到叶子的路径上各个节点着色方式的限制,
红黑树确保没有任意一条从根到叶子的路径超过最短路径的两倍,因此红黑树是一种弱平衡二叉树。相对于AVL树来说,红黑树的旋转次数少,
对于搜索、插入、删除多的操作下用红黑树。
-
- ConcurrentHashMap的并发度是什么?
ConcurrentHashMap的并发度就是segment的大小,默认为16,这意味着最多同时可以有16条线程操作ConcurrentHashMap,这也是ConcurrentHashMap对Hashtable的最大优势。
s