Java 我是否正确重写了equals和hashcode?
在我最近的问题中,我被告知我需要重写我的Java 我是否正确重写了equals和hashcode?,java,overriding,equals,hashcode,Java,Overriding,Equals,Hashcode,在我最近的问题中,我被告知我需要重写我的equals和hashcode方法(以及其他方法)。因此,我花了一些时间阅读了几篇文章,并试图提出一个适当的实现 以下是我读到的一些文章: 所有的文章都很好。由于这是我第一次尝试这样做,我只想确保我没有犯一些简单(或愚蠢)的错误 我将使用name来指示我的Person对象是否等同于另一个Person对象。原因是,所有其他变量都可能不同,但名称始终是唯一的 更新以反映建议的更改 public class Person { private
equals
和hashcode
方法(以及其他方法)。因此,我花了一些时间阅读了几篇文章,并试图提出一个适当的实现
以下是我读到的一些文章:
name
来指示我的Person
对象是否等同于另一个Person
对象。原因是,所有其他变量都可能不同,但名称始终是唯一的
更新以反映建议的更改
public class Person {
private String name;
private int p_number;
private String address;
//other variables
public Person(String a_name) {
name = a_name;
}
public String getName() {
return name;
}
//other getters and setters
@Override
public boolean equals(Object o) {
if(o == null)
return false;
if(o == this)
return true;
if(!(o instanceof Person))
return false;
Person p = (Person) o;
return name.equals(p.name));
}
@Override
public int hashCode() {
return name.hashCode();
}
}
我的问题如下:
name
是唯一确定唯一性的变量,我是否需要检查hashcode
中的任何其他变量equals()
中:
缺少false
,您可以:
// Both are Person instances, no need to use the accessor here
return name.equals(p.name);
至于hashCode()
,只需返回name.hashCode()
此外,名称可以为空吗?你的方法似乎不能解释这一点。(编辑:答案:否)
关于你的问题:
由于name是唯一确定唯一性的变量,我是否需要检查hashcode中的任何其他变量
不,当然不是!如果您的姓名相同但年龄不同,这将导致相等对象的哈希代码不同,这违反了对象
约定
我在StackOverflow上读到,不久前31被选为一个好的素数,但现在选择一个更大的素数更好?有人能证实或否认这一说法吗?(索赔是在上面的第三个链接中提出的)
这个,不知道
为了更全面地了解.equals()
/.hashCode()
合同,我将提到一个来自Guava的实用程序类:。此抽象类对于给定对象的实现
类可以让您创建集
s,从而映射
s,将这些对象作为成员(键),就好像它们对这两个函数有不同的实现:
Equivalence<MyClass> eq = ....;
Set<Equivalence.Wrapper<MyClass>> set = ...;
set.add(eq.wrap(myClassInstance));
等效等式=。。。。;
集合=。。。;
set.add(eq.wrap(myClassInstance));
这实际上在某些情况下非常有用…在equals()
中:
缺少false
,您可以:
// Both are Person instances, no need to use the accessor here
return name.equals(p.name);
至于hashCode()
,只需返回name.hashCode()
此外,名称可以为空吗?你的方法似乎不能解释这一点。(编辑:答案:否)
关于你的问题:
由于name是唯一确定唯一性的变量,我是否需要检查hashcode中的任何其他变量
不,当然不是!如果您的姓名相同但年龄不同,这将导致相等对象的哈希代码不同,这违反了对象
约定
我在StackOverflow上读到,不久前31被选为一个好的素数,但现在选择一个更大的素数更好?有人能证实或否认这一说法吗?(索赔是在上面的第三个链接中提出的)
这个,不知道
为了更全面地了解.equals()
/.hashCode()
合同,我将提到一个来自Guava的实用程序类:。此抽象类对于给定对象的实现
类可以让您创建集
s,从而映射
s,将这些对象作为成员(键),就好像它们对这两个函数有不同的实现:
Equivalence<MyClass> eq = ....;
Set<Equivalence.Wrapper<MyClass>> set = ...;
set.add(eq.wrap(myClassInstance));
等效等式=。。。。;
集合=。。。;
set.add(eq.wrap(myClassInstance));
这在某些情况下非常有用…您的
equals
在所有情况下都需要返回一个值,只需更改结尾部分以返回名称。equals
@Override
public boolean equals(Object o) {
...
return name.equals(o.getName());
}
此外,您的hashcode实际上是有害的,它所做的只是使用name.hashcode()
,然后将其乘以31,最好直接使用名称中的默认Java字符串hashcode
@Override
public int hashCode() {
return name.hashCode();
}
您的
equals
在所有情况下都需要返回一个值,只需更改结束部分以返回名称。equals
@Override
public boolean equals(Object o) {
...
return name.equals(o.getName());
}
此外,您的hashcode实际上是有害的,它所做的只是使用name.hashcode()
,然后将其乘以31,最好直接使用名称中的默认Java字符串hashcode
@Override
public int hashCode() {
return name.hashCode();
}
很好,不,名称不能为空。谢谢你的快速回复!我将进行这些修复请注意对
.equals()
的编辑:使用o
访问name
时无需使用访问器。另一件事:Person
可以扩展吗?谢谢,我注意到了您(以及greedybuddha)所做的更改,并将在编辑该类时对其进行检查。暂不延长Person
的有效期。不过,我也没有计划在将来扩展它。遗憾的是,您也有setter,否则我建议将实例变量final
。或者你可以使用一个构建器来构建Person
对象,这将允许该类是不可变的,这是一个很好的加号。谢谢你的快速回复!我将进行这些修复注意编辑.equals()
:无需使用访问者通过o
访问name
。另一件事:Person
可以扩展吗?谢谢,我注意到了您(以及greedybuddha)所做的更改,并将在我进行edi时对其进行检查