LinkedHashMap(0, 0.75f, true) LinkedHashMap的加载因子和初始容量分配

时间:2020-12-27 19:14:56

今天上午在CSDN的论坛里看到有朋友提的问题如下:

 

[java]  view plain  copy
 
  1. /** @param maxSize Maximum sum of the sizes of the Bitmaps in this cache */  
  2.     public LruMemoryCache(int maxSize) {  
  3.         if (maxSize <= 0) {  
  4.             throw new IllegalArgumentException("maxSize <= 0");  
  5.         }  
  6.         this.maxSize = maxSize;  
  7.         this.map = new LinkedHashMap<String, Bitmap>(0, 0.75f, true);  
  8.     }  

 

       上面这段代码是github上面一个比较有名的开源项目中的一段,大概就是一个用LinkedHashMap来实现lru,我的问题LinkedHashMap构造函数的前2个参数,初始容量竟然是0?那加载因子0.75有何意义?据我所知,扩展容量时,是用初始容量*加载因子,这样的话,这个扩展的容量不是始终都是0了吗,初始也为0,扩展也为0,那这个hashmap还有何意义?不知道哪里理解错了

第一个网友的回答如下:

       你再看看HashMap的源代码,看看是怎么扩容的。
       上面这段代码没有什么特别的地方,只是初始化了一个长度为0的HashMap,顺便设置了LinkedHashMap的访问顺序(第三个参数),  这种情况一般是创建时不确定Map中是否会有值及几个值,比较保守的写法,不想浪费空间。
        默认的构造方法是长度为16, 如果你不确定map中是否能放够16个键值,那么16的长度就浪费了。这样写也有不利的地方,多了几次运行时的扩容操作,作者可能认为空间更重要吧。

第二个网友的回答如下:

       看看源码就知道了

       其实第一个参数是你要设置的初始大小;而程序内部实际的初始大小是1;
       如果你设置的初始大小(initialCapacity)小于1, 那么map大小就是默认的1;
       否则会不断左移(乘2)直到capacity大于你设置的initialCapacity;

 

[java]  view plain  copy
 
  1.  public LinkedHashMap(int initialCapacity,  
  2.          float loadFactor,  
  3.                         boolean accessOrder) {  
  4.        super(initialCapacity, loadFactor);//这里调用父类HashMap的构造方法;  
  5.        this.accessOrder = accessOrder;  
  6.    }  
  7. public HashMap(int initialCapacity, float loadFactor) {  
  8.        if (initialCapacity < 0)  
  9.            throw new IllegalArgumentException("Illegal initial capacity: " +  
  10.                                               initialCapacity);  
  11.        if (initialCapacity > MAXIMUM_CAPACITY)  
  12.            initialCapacity = MAXIMUM_CAPACITY;  
  13.        if (loadFactor <= 0 || Float.isNaN(loadFactor))  
  14.            throw new IllegalArgumentException("Illegal load factor: " +  
  15.                                               loadFactor);  
  16.   
  17.        // Find a power of 2 >= initialCapacity  
  18.        int capacity = 1;  // 默认是1  
  19.        while (capacity < initialCapacity)//不断翻倍直到大于人为设置的大小  
  20.            capacity <<= 1;  
  21.   
  22.        this.loadFactor = loadFactor;  
  23.        threshold = (int)(capacity * loadFactor);//的确如你所言,后面如果需要增大长度,按照capacity*loadFactor取整后增长;  
  24.        table = new Entry[capacity];  
  25.        init();  
  26.    }  


       上面的两位网友的答复其实都已解答了发帖网友的疑问,第一位回复的网友显然是翻看过LinkedHashMap类的源码的。我写这篇博文目的在于记录分享,因为我之前在翻看Android 开源框架Universal-Image-Loader(在github上的地址:https://github.com/nostra13/Android-Universal-Image-Loader)里的那段源码时,也是不太明白作者意欲何为?当时没深究,今天上午在论坛里看到发帖的网友的提问及两位网友的答复,觉得这个问题有必要记录下。