码迷,mamicode.com
首页 > 其他好文 > 详细

HashMap 初始化时 容量设定

时间:2018-02-26 11:22:38      阅读:1887      评论:0      收藏:0      [点我收藏+]

标签:pac   fan   www   一个   构造方法   个数   没有   inf   image   

问题引入

注:本文代码源自java 9

  • 阿里的插件对于初始化HashMap时,调用无参构造方法,提示如下:
    技术分享图片
  • 那么问题来了,如果已知需要向 map 中 put n次,那么需要设定初始容量为多少?
  • 单纯的我今天上午还认为是合理的容量是 n + 1 即可,直到看了源码;
  • 应注意,map.size 获取的是当前map中键值对的个数,而不是容量。

当初始化的时候,没有指定容量,情况如何?

1.直接调用如下构造函数(无参)

    /**
     * Constructs an empty {@code 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
    }
  • 首先应该清楚,loadFactor 是 装载因子(通俗来讲,若值为0.5f,那么当map元素达到 容量*0.5f的时候,就应该做扩容等操作)
  • HashMap对象实际上只有 threshold(临界值,阈值) 属性,每次put()后,需要比较的是阈值与size(map中已有键值对的个数)
  • 至于容量属性,实际上各个方法中用的是 transient Node<K,V>[] table; 中 table 的长度
    具体可参考 http://www.importnew.com/20386.html
  • 其次,作为一个没有被赋值的全局变量,在类的构造函数中必须要赋值。
  • 本构造方法上说明:构造了一个空的HashMap,默认容量为16,装载因子为0.75。
  • 然而可以清楚地看到,此构造方法只是将常量 DEFAULT_LOAD_FACTOR赋值给装载因子,但没有设定容量。
  • 当调用put()时,如下方式设定了初始容量。
  • 调用 putVal(hash(key), key, value, false, true)
public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }
  • 在putVal()中,进入第一个if,调用resize()
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
               boolean evict) {
    Node<K,V>[] tab; Node<K,V> p; int n, i;
    if ((tab = table) == null || (n = tab.length) == 0)
        n = (tab = resize()).length;
   //省略无关代码
}
  • 在下方代码中,oldCap 与 oldThr 初始都为0,故直接进入else{}
final Node<K,V>[] resize() {
    Node<K,V>[] oldTab = table;
    int oldCap = (oldTab == null) ? 0 : oldTab.length;
    int oldThr = threshold;
    int newCap, newThr = 0;
    if (oldCap > 0) 
       //省略无关代码
    else if (oldThr > 0) // initial capacity was placed in threshold
        //省略无关代码
    else {               // zero initial threshold signifies using defaults
        newCap = DEFAULT_INITIAL_CAPACITY;//设定 newCap  = 16
        newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);//设定 newThr  = 16 * 0.75 = 12
    }
        threshold = newThr;//将对象的 threshold(临界值,阈值) 属性设置为 newThr 
            Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
        table = //将对象的 table 属性设置为刚实例化的 newTab 
        //省略无关代码
        return newTab;//并返回
    
  • 综上,默认无参的构造方法设定初始容量为16,装载因子为0.75f。

当我们指定容量为n的时候,情况如何?

参考文章:http://blog.csdn.net/fan2012huan/article/details/51087722

HashMap 初始化时 容量设定

标签:pac   fan   www   一个   构造方法   个数   没有   inf   image   

原文地址:https://www.cnblogs.com/kangkaii/p/8471619.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!