MAP哈希表( 三 )


8.为什么不直接使用()处理后的哈希值直接作为table的下标?
()方法返回的是int整数类型 , 其范围为-(2 ^ 31)~(2 ^ 31 - 1) , 约有40亿个映射空间 , 而的容量范围是在16(初始化默认值)~2 ^ 30 , 通常情况下是取不到最大值的 , 并且设备上也难以提供这么多的存储空间 , 从而导致通过()计算出的哈希值可能不在数组大小范围内 , 进而无法匹配存储位置
9. 的长度为什么是2的幂次方 , 为什么是两次扰动?
为了能让存取高效 , 尽量较少碰撞 , 也就是要尽量把数据分配均匀
我们首先可能会想到采用%取余的操作来实现 。但是 , 重点来了:“取余(%)操作中如果除数是2的幂次则等价于与其除数减一的与(&)操作(也就是说 hash%==hash&(-1)的前提是是2的 n 次方;) 。” 并且 采用二进制位操作 & , 相对于%能够提高运算效率 , 这就解释了的长度为什么是2的幂次方
那为什么是两次扰动呢?
这样就是加大哈希值低位的随机性 , 使得分布更均匀 , 从而提高对应数组存储下标位置的随机性&均匀性 , 最终减少Hash冲突 , 两次就够了 , 已经达到了高位低位同时参与运算的目的
10. 和的区别
①对整个桶数组进行了分割分段() , 然后在每一个分段上都用lock锁进行保护 , 相对于的锁的粒度更精细了一些 , 并发性能更好(JDK1.8之后启用了一种全新的方式实现,利用CAS算法 。直接用 Node 数组+链表+红黑树的数据结构来实现 , 并发控制使用和 CAS 来操作)而没有锁机制 , 不是线程安全的
②的键值对允许有null , 但是都不允许
辅助工具类
11. Array 和有何区别?
①Array 可以存储基本数据类型和对象 ,  只能存储对象
②Array 是指定固定大小的 , 而大小是自动扩展的
③Array 内置方法没有多 , 比如 、、 等方法只有有
12.和 的区别?
①接口实际上是出自java.lang包 , 它有一个 ( obj)方法用来排序
②接口实际上是出自 java.util 包 , 它有一个( obj1,obj2)方法用来排序
【MAP哈希表】一般我们需要对一个集合使用自定义排序时 , 我们就要重写方法或方法