Java HashMap初始容量的取值示例

HashMap中底层数据的长度总是2的n次方

在某个元素存入HashMap底层数组时,为确定其位置,最直接的方式是对其取模,这样能够均匀的分布到数组中。这里比较取巧的是,当数组长为2的n次方时,通过h&(length-1)能够高效的算出hash值。

/**
 * Returns index for hash code h.
 */
static int indexFor(int h, int length) {
    // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
    return h & (length-1);
}
HashMap默认初始容量为16,负载因子loadFactor为0.75,也就是说只能存储12个元素,当put第13个元素时就需要resize数组将容量扩充到32。

确定初始容量

最初一直通过手动计算算出初始容量,算出大于数据size的最小的2的n次方,当然也要考虑加载因子。这样每次计算都很麻烦,将负载因子设为1可以简单计算。但查看源码,HashMap做了Size计算。

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 <= 0 || Float.isNaN(loadFactor))
        throw new IllegalArgumentException("Illegal load factor: " +
                                           loadFactor);
 
    this.loadFactor = loadFactor;
    threshold = initialCapacity;
    init();
}
/**
 * Inflates the table.
 */
private void inflateTable(int toSize) {
    // Find a power of 2 >= toSize
    int capacity = roundUpToPowerOf2(toSize);
 
    threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
    table = new Entry[capacity];
    initHashSeedAsNeeded(capacity);
}
 
private static int roundUpToPowerOf2(int number) {
    // assert number >= 0 : "number must be non-negative";
    return number >= MAXIMUM_CAPACITY
            ? MAXIMUM_CAPACITY
            : (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1;
}

可以看出我们定义的initialCapacity先赋值于threshold,threshold为rehash的标志。在inflateTable中会算上loadFactor重新计算threshold的值。所以要避免HashMap使用过程出现rehash,initialCapacity不能直接传元素个数,initialCapacity必须大于等于(元素length/loadFactor),所以负载因子使用默认值0.75,初始容量设为1.333…*length,一般习惯1.4*length。

函数highestOneBit

在JDK1.6时,取最小的2的n次方使用while循环连续比较,在jdk1.7时如上做了改动。先取number值最高位,再向左移一位。highestOneBit实现:

public static int highestOneBit(int i) {
    // HD, Figure 3-1
    i |= (i >>  1);
    i |= (i >>  2);
    i |= (i >>  4);
    i |= (i >>  8);
    i |= (i >> 16);
    return i - (i >>> 1);
}

通过移位后i的值从最高位1开始都是1,在右移相减得到最高位的值。

时间: 2024-10-23 12:57:11

Java HashMap初始容量的取值示例的相关文章

jquery通过name快速取值示例

 jquery中快速取值的方法有很多,在本文为大家介绍下通过name实现快速取值,感兴趣的朋友可以参考下 代码如下: function getValues_ByName() {  var order = [];  $("[name=chkbox_id]:checked").each(function () {  order.push($(this).val());  });  var values = order.join(',');  if (values == "&quo

jquery 通过name快速取值示例_jquery

复制代码 代码如下: function getValues_ByName() { var order = []; $("[name=chkbox_id]:checked").each(function () { order.push($(this).val()); }); var values = order.join(','); if (values == "") { alert("选项不能为空!"); return; } else { ale

怎样用java实现 c#中Datarow[索引] 的取值的方式 ?

问题描述 怎样用java实现 c#中Datarow[索引] 的取值的方式 ? 怎样用java实现 c#中Datarow[索引] 的取值的方式 ?比如我有定义一个这样的数组:HashMap map=new HashMap<>();如何实现如下取值?map[""key""]=""值""; 解决方案 java不支持索引器,所以给出的解决方案就是使用方法代替(其实C#的索引器也是方法,只是写法上简化了点)比如map.get

java-JAVA字符串形式数值数组取值

问题描述 JAVA字符串形式数值数组取值 字符串格式是这样的[[x1,y1,v1],[x2,y2,v2],[x3,y3,v3] ....[xn,yn,vn]].想按顺序取出里面的v1...vn放到一个数组或者集合里,怎样最简洁? 解决方案 String s="[[x1,y1,v1],[x2,y2,v2],[x3,y3,v3] ....[xn,yn,vn]]"; Pattern pattern=Pattern.compile("vd+"); Matcher match

JAVA HashMap详细介绍和示例_java

第1部分 HashMap介绍HashMap简介HashMap 是一个散列表,它存储的内容是键值对(key-value)映射.HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.Serializable接口.HashMap 的实现不是同步的,这意味着它不是线程安全的.它的key.value都可以为null.此外,HashMap中的映射不是有序的.HashMap 的实例有两个参数影响其性能:"初始容量" 和 "加载因子".容量

用el表达式怎么取 hashmap的值?(通过键取值)

问题描述 <c:forEach items="${hash}" var="li" varStatus="status2"> <c:if test="${status2.index == 0}"> <th class="column" scope="row"><input type="checkbox" id="rec

java数组-JAVA中取值还是会取到重复的

问题描述 JAVA中取值还是会取到重复的 如图中代码,为何还会取到重复的 解决方案 do-while 循环的问题吧 ,=是赋值, == 才是判断相等 while(ss == false) 解决方案二: 而且这个循环的条件应该是while(ss)而不是while(!ss) 解决方案三: 循环条件有点问题. while(ss == false) 解决方案四: =是赋值: == 是值判断:===是属性值都判断:while的判断需要修改 解决方案五: 你的do-while循环里面的,一点作用都没有起到,

概率取值-oracle 或者 java 通过概率取得对应的值

问题描述 oracle 或者 java 通过概率取得对应的值 现在我有1张表 字段如下 ID QUEUE_PRIORITY1 1002 2003 100004 500 QUEUE_PRIORITY 表示 被取到的概率值 我想 通过概率 取2个值出来 意思就是 取到 2的概率 是 200/(100+200+10000+500) 怎么排序法 求大大指教 解决方案 你的意思是根据概率进行排序么那么你给出的数据根据概率进行排序 升序是1 1002 2004 5003 10000毫无疑问只要排序QUEUE

求教,java里面request.getParameter取值偶现是null,post也有长度限制?

问题描述 求教,java里面request.getParameter取值偶现是null,post也有长度限制? string a = request.getParameter("ids"); 前台是 $.ajax({ type: 'POST',dataType: 'TEXT',cache: false,data: 'ids=' +ids 现在看到的规律是ids短一点就有正常的值, ids长了,a就直接是null了 . 求大神帮忙看一下~ 奇怪的是,尝试用@RequestBody Str