class EventInfo{
private String name;
private Map<String, Integer> info
}
然后我想创建一个地图:
Map<EventInfo, String> map = new HashMap<EventInfo, String>();
我需要明确地实现hashCode()和equals()吗?谢谢。
class EventInfo{
private String name;
private Map<String, Integer> info
}
Map<EventInfo, String> map = new HashMap<EventInfo, String>();
我需要明确地实现hashCode()和equals()吗?谢谢。
是的,你需要。 HashMap
的工作原理是通过计算键的哈希码并将其用作基准点来实现的。如果 hashCode
函数没有被覆盖(您自己),则它将使用内存地址,而 equals
将与 ==
相同。
如果您使用 Eclipse,则可以让它为您生成。单击 源 菜单 → 生成 hashCode() 和 equals()。
如果您没有 Eclipse,下面是一些应该有效的代码。(我在 Eclipse 中生成了这些代码,如上所述。)
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((info == null) ? 0 : info.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof EventInfo)) {
return false;
}
EventInfo other = (EventInfo) obj;
if (info == null) {
if (other.info != null) {
return false;
}
} else if (!info.equals(other.info)) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
user697911
好 :) - wchargin是的,你需要它们,否则你将无法比较两个EventInfo(并且你的映射将无法工作)。
这取决于您想要发生什么。如果两个不同的EventInfo
实例具有相同的name
和info
,应该产生两个不同的键,则无需实现equals
和hashCode
。
所以
EventInfo info1 = new EventInfo();
info1.setName("myname");
info1.setInfo(null);
EventInfo info2 = new EventInfo();
info2.setName("myname");
info2.setInfo(null);
info1.equals(info2)
会返回false,info1.hashCode()
的值也与info2.hashCode()
不同。
因此,在将它们添加到地图中时:
map.put(info1, "test1");
map.put(info2, "test2");
您会有两个不同的条目。
现在,这可能是期望的行为。例如,如果您的EventInfo
正在收集不同的事件,则具有相同数据的两个不同事件可能希望成为两个不同的条目。
equals
和hashCode
协定也适用于Set
。
例如,如果您的事件信息包含鼠标点击,则很可能希望最终得到:
Set<EventInfo> collectedEvents = new HashSet<EventInfo>();
collectedEvents.add(info1);
collectedEvents.add(info2);
不只有一个收集事件,而是有两个...
希望我表达清楚了...
编辑:
如果上述的set和map只应该包含单个条目,则可以使用Apache Commons的EqualsBuilder和HashCodeBuilder来简化equals
和hashCode
的实现:
@Override
public boolean equals(Object obj) {
if (obj instanceof EventInfo) {
EventInfo other = (EventInfo) obj;
EqualsBuilder builder = new EqualsBuilder();
builder.append(name, other.name);
builder.append(info, other.info);
return builder.isEquals();
}
return false;
}
@Override
public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder();
builder.append(name);
builder.append(info);
return builder.toHashCode();
}
编辑2:
如果两个EventInfo
实例具有相同的名称,则将它们视为相同可能是合适的,例如,如果name
是某个唯一标识符(我知道对于您特定的对象来说有点牵强,但我在这里进行概括...)