我使用以下代码定义了HashMap
:
final Map<OrderItemEntity, OrderItemEntity> savedOrderItems = new HashMap<OrderItemEntity, OrderItemEntity>();
final ListIterator<DiscreteOrderItemEntity> li = ((BundleOrderItemEntity) oi).getDiscreteOrderItems().listIterator();
while (li.hasNext()) {
final DiscreteOrderItemEntity doi = li.next();
final DiscreteOrderItemEntity savedDoi = (DiscreteOrderItemEntity) orderItemService.saveOrderItem(doi);
savedOrderItems.put(doi, savedDoi);
li.remove();
}
((BundleOrderItemEntity) oi).getDiscreteOrderItems().addAll(doisToAdd);
final BundleOrderItemEntity savedBoi = (BundleOrderItemEntity) orderItemService.saveOrderItem(oi);
savedOrderItems.put(oi, savedBoi);
我将4个项目放入HashMap
。当我调试时,即使size
为4,它也只显示3个元素:
这是它包含的元素列表。
{DiscreteOrderItemEntity@1c29ef3c=DiscreteOrderItemEntity@41949d95, DiscreteOrderItemEntity@2288b93c=DiscreteOrderItemEntity@2288b93c, BundleOrderItemEntity@1b500292=BundleOrderItemEntity@d0f29ce5, DiscreteOrderItemEntity@9203174a=DiscreteOrderItemEntity@9203174a}
可能是什么问题?
答案 0 :(得分:14)
Hashmaps处理冲突。
由于HashMap
仅由16个桶组成,因此元素的哈希值必须减少到跨越 0 和 15 之间的数字(例如hash % 16
)。因此,两个元素可能位于同一个桶中(相同的HashMapNode
)。
您可以检查每个HashMapNode
以找出哪个包含两个元素。
答案 1 :(得分:1)
该机制被解释为enrico.bacis,有一个例子可以重现它:
public class TestJava {
static class TT {
private String field;
@Override
public int hashCode() {
return 1;
}
}
public static void main(String[] args) {
Map<TT, String> test = new HashMap<>();
TT t1 = new TT();
TT t2 = new TT();
test.put(t1, "test2");
test.put(t2, "test2");
test.put(null, "test2");
test.put(null, "test2");
System.out.println(test.toString());
System.out.println(test.size());
}
}
在那里,我们覆盖hashCode
,硬代码返回 1 ,TT
的所有对象都将返回相同的hashCode 1 强>
我们可以深入研究HashMap.java
:
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
我们可以找到当我们将键/值对放入HashMap
时,它会通过对象的哈希码计算hash number
来定位元素在哈希表中的位置。
因此,如果对象哈希码相同,它们将存储在哈希表的同一个桶中。但是这些confilct元素仍然会被存储,因为它们的关键不一样。