Java HashMap初始化大小设置多少合适 | 您所在的位置:网站首页 › 儿歌《大小多少》 › Java HashMap初始化大小设置多少合适 |
修改公司老代码的时候,发现阿里编码规约插件提示HashMap初始化时尽量指定初始值大小,因为设置合理的初始值可以提升性能: HashMap继承自AbstractMap类,实现了Map、Cloneable、java.io.Serializable接口,是基于散列表实现的双列集合,它存储的是key-value键值对映射,每个key-value键值对也被称为一条Entry条目。其中的 key与 value,可以是任意的数据类型,其类型可以相同也可以不同。但一般情况下,key都是String类型,有时候也可以使用Integer类型;value可以是任何类型。并且在HashMap中,最多只能有一个记录的key为null,但可以有多个value的值为null。HashMap中这些键值对(Entry)会分散存储在一个数组当中,这个数组就是HashMap的主体。 HashMap的实例有两个影响其性能的参数:初始容量和装载因子。容量是哈希表中的桶数,初始容量就是创建哈希表时的容量。负载因子是一种度量方法,用来衡量在自动增加哈希表的容量之前,哈希表允许达到的满度。当哈希表中的条目数超过负载因子和当前容量的乘积时,哈希表将被重新哈希(即重新构建内部数据结构),这样哈希表的桶数大约是原来的两倍。 那么在使用HashMap时要求尽量指定初始值,该指定多少合适?(可以直接跳到后面看结论) 一般来说,初始值大小的设定应该根据实际需要进行设置。另外,也建议将初始值大小设置为2的幂次方,这样可以更好地利用HashMap的内部机制,提高程序的运行效率。 如果不设置,默认值是16。 如我截图的代码,就存放2个变量,初始值设置2,但是设置2真的合理吗? 我们可以看一下HashMap的源码,看看它里面是怎么实现的。 不设置初始值的构造方法: /** * Constructs an empty HashMap with the default initial capacity * (16) and the default load factor (0.75). */ public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted }设置初始值的构造方法: /** * Constructs an empty HashMap with the specified initial * capacity and the default load factor (0.75). * * @param initialCapacity the initial capacity. * @throws IllegalArgumentException if the initial capacity is negative. */ public HashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); }this方法的源码: /** * Constructs an empty HashMap with the specified initial * capacity and load factor. * * @param initialCapacity the initial capacity * @param loadFactor the load factor * @throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (loadFactor > 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; }上面的源码可以看出threshold是个阈值,它的计算是根据tableSizeFor方法来的(根据设置的初始值计算的),到达这个阈值就会触发扩容,扩容是会影响性能的。 再看一下putMapEntries方法的源码,看注释的意思是实现了Map.putAll和Map构造函数: /** * Implements Map.putAll and Map constructor. * * @param m the map * @param evict false when initially constructing this map, else * true (relayed to method afterNodeInsertion). */ final void putMapEntries(Map |
CopyRight 2018-2019 实验室设备网 版权所有 |