zoukankan      html  css  js  c++  java
  • HashMap 之 再哈希探究

    HashTable(哈希表)是JDK 1.0时就加入的,效率低,因为线程安全
    为了提高效率,JDK 1.2加入了HashMap(哈希Map),但是线程不安全。
    JDK 1.5 为了解决线程安全的问题,加入了ConcurrentHashMap(并发哈希Map)。
     
    因此一般的选择是:
    1. 单线程——HashMap
    2. 多线程——ConcurrentHashMap
    特点
    1. 允许null--null 键值对
    2. 线程不安全
    3. 不保证顺序
    影响HashMap性能的两个参数
    1. 初始化容量(capacity)——不要太大,默认16
    2. 负载因子(load factor)——不要太小,默认0.75
    再哈希
     
    当哈希表里的entry(键值对)超过一定阈值时,哈希表会进行再哈希(rehash)。再哈希后的哈希表的桶的个数之前的两倍 。(threshold=capacity*factor)
     
    验证 
    public class HashMapL {
        public static void main(String[] args) {
            HashMap<Integer, Integer> hashMap = new HashMap<>();
            hashMap.put(null, null);  //允许空空键值对
            for(int i=0; i<16; i++){
                hashMap.put(i, i);  //自动装箱
            }
    }
    下面来一步步的研究
     
    HashMap<Integer, Integer> hashMap = new HashMap<>();
     
     
    从上图可以看出
     
    负载因子——0.75
    table——null。尚未分配。了解拉链式哈希表的人就会轻易知道它是一个链表数组。
    阈值——0。这个值是在给table分配空间后才会计算
     
    hashMap.put(null, null);
     
     
     
    从上图可以看到,现在table已经初始化了。
    table——拥有一个元素 "null=null",并且从图片最下面可以看到,它是一个包含16个元素的数组
    table的id——24
     
    继续按下一步,直到size=threshold=12,此刻table的id和之前的一样,还是id=24
     
     
    现在再按一次下一步,向HashMap里添加一个元素,让元素的总数size大于阈值threshold
     
     
    变化
     
    id    24-->104
    大小    16-->32
    阈值    12-->24
     
    结论
    1. 当size>threshold时就会进行再哈希。
    2. 再哈希后,HashMap就会自动扩容为之前的2倍,并且用一个新的对象代替原来的对象。
    由此也可得知,自动扩容是需要消耗资源的,要尽量减少自动扩容的发生。
     
    How HashMap works in java,强烈推荐!【没看】
     
    莫问前程
  • 相关阅读:
    dede文章插入分页符不起作用,编辑器中出现分页符,导致文章显示不全
    dedecms 图集标签{dede:productimagelist} {dede:field name='imgurls'}&nbs
    dede织梦怎么修改description的字数
    dede 内容页文章标题显示不全的更改方法
    amazon company
    rapleaf
    nope
    数据库事务隔离级别与锁
    nosql=not only sql
    Lustre是开放源代码的集群文件系统
  • 原文地址:https://www.cnblogs.com/dolphin007/p/4446110.html
Copyright © 2011-2022 走看看