不可变对象(除String
之外的Integer
和其他包装类等)是否适用于hashmap键?
有人可以解释一下吗?
答案 0 :(得分:12)
如果不可变,则对象的哈希码不会改变,并且它允许缓存不同键的哈希码,这使得整个检索过程非常快。 同样对于可变对象,hashCode()可能依赖于可能更改的字段,如果发生这种情况,您将无法在HashMap中找到键(及其值),因为hashCode()返回不同的值。
答案 1 :(得分:9)
您可以在此处找到答案:How HashMap works in Java
String,Integer和其他包装类是HashMap键的自然候选者,String也是最常用的键,因为String是不可变的和final,并且会覆盖equals和hashcode()方法。其他包装类也共享类似的属性。需要不可变性,以防止用于计算hashCode()的字段发生变化,因为如果密钥对象在插入和检索期间返回不同的hashCode,则无法从HashMap获取对象。不可变性是最好的,因为它提供了其他优点以及线程安全性。如果你可以通过仅使某些字段最终来保持你的hashCode相同,那么你也可以使用它。由于在从HashMap检索值对象期间使用了equals()和hashCode()方法,因此密钥对象正确覆盖这些方法并遵循联系非常重要。如果不相等的对象返回不同的哈希码而不是碰撞的机会将会更少,这随后会提高HashMap的性能。
还有另一个讨论堆栈:Why are immutable objects in hashmaps so effective
hashcode和equals方法都用在HashMap的put和get方法中。您需要确保在将其与关键对象一起使用后,始终可以从地图中获取值对象。无论你是否改变了关键对象。但是不可变对象足以实现这一目标。
答案 2 :(得分:2)
如果你的对象是不可变的并且正确地实现了hashcode / equals,你可以将它们用作hashmap中的键。
答案 3 :(得分:2)
让我们假设我有一个班级
MyKey key = new MyKey("shreyansh"); //assume hashCode=1234
myHashMap.put(key, "value");
// Below code will change the key hashCode() and equals()
// but it's location is not changed.
key.setName("jogi"); //assume new hashCode=7890
//below will return null, because HashMap will try to look for key
//in the same index as it was stored but since key is mutated,
//there will be no match and it will return null.
myHashMap.get(new MyKey("shreyansh"));
在这里使用关键字“Shreyansh”访问它时,它将返回nulll