这是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。
什么时候重复发生?在数组中的11个条目或其中一个链接列表中的11个条目之后?我想在数组中有11个条目之后。
由于数组大小为16,只要数组大小小于或等于11,HashMap
就可以在链表中包含许多对象(可能超过16个)。因此,{{默认容量为16的{1}}可以包含超过11/16个对象,而不会重新散列 - 这是对的吗?
答案 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。