登封市城乡建设路网站,网络架构分几层,网站制作知名公司,惠州网站建设哪家好HashMap,1.7与1.8的区别
底层数据结构的区别
JDK 1.8之前#xff1a;
1#xff09;JDK1.8 之前HashMap 底层是数组和链表结合在一起使用也就是链表散列。 2#xff09;HashMap 通过key 的hashCode 经过扰动函数处理过后得到hash 值#xff0c;然后通过(n - 1#xff09…HashMap,1.7与1.8的区别
底层数据结构的区别
JDK 1.8之前
1JDK1.8 之前HashMap 底层是数组和链表结合在一起使用也就是链表散列。 2HashMap 通过key 的hashCode 经过扰动函数处理过后得到hash 值然后通过(n - 1 hash 判断当前元素存放的位置这里的n 指的是数组的长度如果当前位置存在元素的话就判断该元素与要存入的元素的hash 值以及key 是否相同如果相同的话直接覆盖不相同就通过拉链法解决冲突。 3所谓扰动函数指的就是HashMap 的hash 方法。使用hash 方法也就是扰动函数是为了防止一些实现比较差的hashCode() 方法换句话说使用扰动函数之后可以减少碰撞。
JDK 1.8之后
当链表长度大于阈值默认为 8时会首先调用 treeifyBin()方法。这个方法会根据HashMap 数组来决定是否转换为红黑树。只有当数组长度大于或者等于64 的情况下才会执行转换红黑树操作以减少搜索时间。否则就是只是执行resize() 方法对数组扩容。
扩容机制的区别
一般情况下当元素数量超过阈值时便会触发扩容。每次扩容的容量都是之前容量的2 倍。HashMap 的容量是有上限的必须小于130即1073741824。如果容量超出了这个数则不再增长且阈值会被设置为Integer.MAX_VALUE。
JDK7 中的扩容机制:
空参数的构造函数以默认容量、默认负载因子、默认阈值初始化数组。内部数组是空数组。有参构造函数根据参数确定容量、负载因子、阈值等。第一次put 时会初始化数组其容量变为不小于指定容量的2 的幂数然后根据负载因子确定阈值。如果不是第一次扩容则 新容量旧容量x 2 新阈值新容量x 负载因子。
JDK8 的扩容机制:
空参数的构造函数实例化的HashMap 默认内部数组是null即没有实例化。第一次调用put 方法时则会开始第一次初始化扩容长度为16。有参构造函数用于指定容量。会根据指定的正整数找到不小于指定容量的2 的幂数将这个数设置赋值给阈值threshold。第一次调用put 方法时会将阈值赋值给容量 然后让 阈值 容量x 负载因子。如果不是第一次扩容则容量变为原来的2 倍阈值也变为原来的2 倍。容量和阈值都变为原来的2 倍时负载因子还是不变。此外还有几个细节需要注意首次put 时先会触发扩容算是初始化然后存入数据然后判断是否需要扩容不是首次put则不再初始化直接存入数据然后判断是否需要扩容