之前我已经编写了HashMap来存储一些对象,这些对象期望在存储时使用身份。即对象被对待"相同"如果Object.equals()
说的话。
后来我使用内容评估范例为这些对象的类编写了hashCode()
和equals()
方法。我的上一个HashMap
立即停止工作,因为对象正在变异并变得不平等。
如何插入一些简单的解决方法,使早期的代码工作?可能有办法强制HashMap
使用身份,尽管定义了equals()
和hashCode()
方法?
答案 0 :(得分:5)
简单回答:
答案很长:
在可变属性上使用equals
和hashCode
非常糟糕的做法。事实上,如果你从逻辑上考虑这个问题,那么Map
就会停止工作。
想象一下,我有ColourWrapper
课程:
class ColourWrapper {
private Color color;
//getter/setter omitted
@Override
public int hashCode() {
int hash = 3;
hash = 83 * hash + Objects.hashCode(this.color);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ColourWrapper other = (ColourWrapper) obj;
if (!Objects.equals(this.color, other.color)) {
return false;
}
return true;
}
}
现在我将ColourWrapper wrapper
包裹Color.RED
放入我的Map
。我稍后将此包装器的颜色更改为Color.GREEN
。现在我想将值映射到wrapper
,我该怎么做?
实际上我不能。 Map
已经将wrapper
分配给与其哈希码(-65287
)对应的存储桶,现在我将包装的Color
变为绿色,并且哈希码发生变化。< / p>
Map
当然没有告知这个,所以当哈希码改变时,它的桶不会。它现在“迷失”了。
如果您计划在class
中使用Map
作为关键字,那么应该是不可变的。为了更改映射: