Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我需要实现hashCode()和equals()方法吗?_Java_Equals_Hashcode - Fatal编程技术网

Java 我需要实现hashCode()和equals()方法吗?

Java 我需要实现hashCode()和equals()方法吗?,java,equals,hashcode,Java,Equals,Hashcode,如果我有一个map和一个对象作为map键,那么默认的hash和equals方法就足够了吗 class EventInfo{ private String name; private Map<String, Integer> info } class事件信息{ 私有字符串名称; 私人地图信息 } 然后我想创建一个地图: Map<EventInfo, String> map = new HashMap<EventInfo, String>(

如果我有一个map和一个对象作为map键,那么默认的hash和equals方法就足够了吗

class EventInfo{

    private String name;
    private Map<String, Integer> info
 }
class事件信息{
私有字符串名称;
私人地图信息
}
然后我想创建一个地图:

Map<EventInfo, String> map = new HashMap<EventInfo, String>();
Map Map=newhashmap();

我是否必须显式实现hashCode()和equals()?谢谢。

是的,您需要它们,否则您将无法比较两个事件信息(并且您的地图将不起作用)。

是的,您需要
HashMap
s通过计算密钥的哈希代码并将其用作基点来工作。如果
hashCode
函数没有被(您)覆盖,那么它将使用内存地址,
equals
将与
=
相同

如果您在Eclipse中,它将为您生成它们。单击源菜单→ 生成hashCode()和equals()

如果您没有Eclipse,这里有一些应该可以工作。(我在Eclipse中生成了这些,如上所述。)


严格地说,不是。hashCode()和equals()的默认实现将产生应该工作的结果。看

我的理解是hashCode()的默认实现通过获取对象在内存中的地址并转换为整数来工作,而equals()的默认实现仅当两个对象实际上是同一个对象时才返回true

实际上,您可以(也应该)改进这两种实现。例如,这两种方法都应该忽略不重要的对象成员。此外,equals()可能希望递归地比较对象中的引用


在特定情况下,如果两个对象引用同一个字符串,或者两个字符串相等,并且两个映射相同或相等,则可以将equals()定义为true。我认为WChargin为您提供了非常好的实现。

取决于您希望发生什么。如果两个不同的
EventInfo
实例具有相同的
名称
info
会产生两个不同的键,那么您不需要实现
equals
hashCode

所以

info1.equals(info2)
将返回false,
info1.hashCode()
将向
info2.hashCode()
返回不同的值

因此,将它们添加到地图时:

map.put(info1, "test1");
map.put(info2, "test2");
您将有两个不同的条目

现在,这可能是理想的行为。例如,如果您的
EventInfo
正在收集不同的事件,则两个具有相同数据的不同事件很可能希望成为两个不同的条目

equals
hashCode
合同也适用于
集合

因此,例如,如果您的事件信息包含鼠标单击,那么您可能希望以以下方式结束:

Set<EventInfo> collectedEvents = new HashSet<EventInfo>();
collectedEvents.add(info1);
collectedEvents.add(info2);
编辑2:


如果两个
EventInfo
实例被认为是相同的,如果它们具有相同的名称,例如如果
name
是某个唯一的标识符(我知道这对于您的特定对象来说有点牵强,但我在这里概括一下…)

默认的equals和hashcode方法只使用对象的地址。如果你想让两个等价的对象进行相等的比较,你需要显式的方法(这样你就可以,例如,找到一个插入到地图中的对象)。酷!不需要任何修改@用户697911:我很高兴能为您提供帮助。我注意到你问了20个问题,但没有接受任何答案。如果你找到一个适合你的答案,请考虑点击答案旁边的绿色复选标记,或者至少给它一个不错的投票。您还可以获得接受答案的代表@user697911:请查看中的图像。@user697911:不,它仍然没有被接受。你能看到复选标记吗?如果你点击大纲(答案分数和上下按钮的正下方),它应该变成一个绿色的复选标记。你知道,看看这个,我不确定自动生成的equals()方法是否正确。如果
other
EventInfo
的子类,该怎么办?
map.put(info1, "test1");
map.put(info2, "test2");
Set<EventInfo> collectedEvents = new HashSet<EventInfo>();
collectedEvents.add(info1);
collectedEvents.add(info2);
@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();
}