为什么Java HashMap在调试视图中包含空值

时间:2014-12-01 13:27:22

标签: java eclipse hashmap

调试时我发现了一种奇怪的行为。

我有一个HashMap<Integer, Set<Term>>(Term是一个只包含字符串的类),正常的toString()显示了这个:

enter image description here

当我点击HashMap的table属性时,我得到了这个:

enter image description here

我现在的问题,为什么表toString()中有空值?

编辑:感谢您的快速解答!如果可以的话,我会接受所有这些......

6 个答案:

答案 0 :(得分:2)

因为您正在使用的Map实现正在使用一组HashBuckets,其中一些在开始时为NULL(由initialCapacity决定)。如果超过条目数,它将开始为对象创建更多HashBuckets / slots。将此视为HashMap自动为您创建的增长储备。

了解更多: https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html

答案 1 :(得分:2)

HashMap将其条目存储在哈希表中。这是一个数组,哈希函数将键映射到其中一个数组条目(也称为哈希桶)。

哈希桶总是至少20%为空。如果不是,则调整数组大小以确保有足够的可用空间。

原因是当哈希表被填满时,哈希之间的冲突越来越可能。如果碰撞太频繁,您将失去HashMap的所有优点。太满了,你的HashMap也不会比LinkedList好(是的,LinkedList,而不是ArrayList)。它可能会更糟。

答案 2 :(得分:2)

HashMap是一个Map实现,其关键特性是恒定时间O(1)查找。

计算机科学中具有恒定时间查找的唯一数据结构是固定长度的数组。当您初始化HashMap时,它会创建一个固定长度的数组,当您的条目超出当前数组的大小时,它将展开。

编辑:@kutschkem指出,当条目数大约是当前数组大小的80%时,java.util.HashMap会扩展其固定长度数组,而不是当条目超过当前数组时#& 39;尺寸。

答案 3 :(得分:1)

这就是哈希映射的工作原理:一个大型数组(table),对于某些键,尝试了以下表项:

table[key.hashCode() % table.length]

然后使用该表槽。如果已存在不是equals(key)的密钥,则使用重新散列。 因此,最初该表仅包含空值,并且大小为initialCapacity。当哈希映射变得太满(loadFactor)时,可以生成数组。

答案 4 :(得分:1)

HashMap在内部使用数组来存储条目。非常简化,它执行类似array_index = hashcode % array_length的操作(再次:非常简化,因为它还需要处理哈希冲突等)。此内部数组通常大于您在HashMap中存储的元素数 - 否则,每次向其添加元素时都必须调整数组的大小。所以你看到的null是数组中尚未使用的插槽。

答案 5 :(得分:1)

这是正常行为。

有空值,因为表数组已初始化为填充空值,并使用null表示该散列桶中没有存储值。

提供的toString()函数不会跳过它们,因为看到它们对调试HashMap实现的folds很有用。

如果你想看到没有空值的内容,你必须编写自己的显示函数,或者通过继承HashMap并重写toString()或者在你的代码中的某处提供一个便利函数。