默认容量为16的HashMap可以包含超过11/16个对象而无需重新散列 - 这是正确的吗?

时间:2016-11-28 17:13:53

标签: java hashmap

这是What is the initial size of Array in HashMap Architecture?的后续问题。

从这个问题我理解 private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; Form1 frm = //want to set 'frm' to the existing, instantiated form1 already running. string indata = sp.ReadExisting(); //stores the char that fired the event into 'indata' if (indata == "\r") //check to see if char received indicates end of measurement, yes tells main form to add measurement, no tells to add char to string { frm.pendingMeasurement = true; MessageBox.Show(myString); } else myString += indata; } 的初始容量默认为16,在调整大小之前允许最多11个条目,因为默认加载因子是0.75。

  1. 什么时候重复发生?在数组中的11个条目或其中一个链接列表中的11个条目之后?我想在数组中有11个条目之后。

  2. 由于数组大小为16,只要数组大小小于或等于11,HashMap就可以在链表中包含许多对象(可能超过16个)。因此,{{默认容量为16的{1}}可以包含超过11/16个对象,而不会重新散列 - 这是对的吗?

2 个答案:

答案 0 :(得分:2)

  

因此,默认容量为16的HashMap可以包含超过11/16个对象(K,V)而无需重新散列

这是使用作为度量占用的桶数量的明显缺陷。另一个问题是你需要保持使用的大小和数量的桶。

相反,它是使用的size(),因此size()是唯一决定何时发生rehashing的事情,无论它是如何排列的。

来自Java 8的源代码

final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
    int s = m.size();
    if (s > 0) {
        if (table == null) { // pre-size
            float ft = ((float)s / loadFactor) + 1.0F;
            int t = ((ft < (float)MAXIMUM_CAPACITY) ?
                     (int)ft : MAXIMUM_CAPACITY);
            if (t > threshold)
                threshold = tableSizeFor(t);
        }
        else if (s > threshold)
            resize();

答案 1 :(得分:0)

我认为您对HashMap实现过分注意,这可能并且确实会随着时间的推移而发生变化。根据地图本身而不是内部数据结构来思考。

  

什么时候重复发生?在数组中的11个条目或其中一个链接列表中的11个条目之后?我想在数组中有11个条目之后。

既不; 地图包含11个条目后,地图会调整大小。这些条目都可以在他们自己的桶中,也可以在一个桶中以11个深度链接。

  

由于数组大小为16,只要数组大小小于或等于11,HashMap就可以在链表中包含许多对象(可能超过16个)。因此,默认容量为16的HashMap可以包含更多比没有重复的11/16个对象 - 这是对的吗?

没有。虽然您可以创建自己的哈希表实现来存储比桶更多的元素,但是这样做会牺牲效率。只要地图中的元素数量超过加载因子,JDK的HashMap实现就会调整后备数组的大小。这些元素是全部在同一个桶中还是分布在它们之间并不重要。在docs

  

当哈希表中的条目数超过加载因子和当前容量的乘积时,哈希表将被重新哈希(即,重建内部数据结构),以便哈希表的数量大约是哈希表的两倍。桶中。

例如,如果您有HashMap(默认加载和容量)当前包含11个条目,并且您调用.put()来插入第12个条目,则地图将为resized