该应用程序将说明用户是否猜到了他引入的两种颜色组合。
我正在使用HashMap来保存“TwoColors”对象和布尔值。 TwoColors类是下一个:
public class TwoColors{
public MyColor color1;
public MyColor color2;
public TwoColors(MyColor color1, MyColor color2){
this.color1 = color1;
this.color2 = color2;
}
@Override
public boolean equals(Object obj) {
TwoColors o = (TwoColors) obj;
return color1 == o.color1 && color2 == o.color2;
}
}
MyColor是一个枚举
public enum MyColor{
RED,BLUE,YELLOW,BROWN;
}
我测试放置一个TwoColor对象键并打印其值
public static void main(String[] args){
HashMap<TwoColors, Boolean> hash = new HashMap<TwoColors, Boolean>();
hash.put(new TwoColors(MyColor.RED,MyColor.BLUE),new Boolean(true));
System.out.println(hash.get(new TwoColors(MyColor.RED,MyColor.BLUE)));
}
上面的代码输出null
虽然我已经覆盖了TwoColors的equals方法。知道我在这里缺少什么吗?
答案 0 :(得分:2)
当你重写equals时,你应该总是覆盖hashcode,如果你在尝试通过调用get来查找值时不这样做,你的hashmap就找不到它。
阅读this帖子以获取理解。
使用Eclipse可以获得的默认哈希码:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((color1 == null) ? 0 : color1.hashCode());
result = prime * result + ((color2 == null) ? 0 : color2.hashCode());
return result;
}
此外,您的equals实施不是生产代码,这意味着它无法正确实现。您的实施对ClassCastException
开放,因为您将其盲目地投射到MyColor
,因此您的实施容易NullPointerException
。
它应该像这样:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TwoColors other = (TwoColors) obj;
if (color1 != other.color1)
return false;
if (color2 != other.color2)
return false;
return true;
}
在检查字段值之前检查两个引用是否相同,检查是否为null,检查类是否相等,最后检查字段值。
虽然Apache也有HashCodeBuilder
和EqualsBuilder
答案 1 :(得分:1)
来自Java文档:
请注意,一旦覆盖此方法[
hashCode
],通常需要覆盖equals
方法,以便维护hashCode方法的常规协定,该方法指出相等的对象必须具有相等的哈希码。
由于MyColor
是枚举,因此将此代码添加到您的类中应修复它:
@Override
public int hashCode() {
return color1.ordinal() + 31*color2.ordinal();
}