什么问题/陷阱,必须重写时,必须考虑equals和hashCode?
昨天我接受了两个小时的技术电话采访(我通过了,哇喔!),但我完全消除了关于Java中动态绑定的以下问题.这让我感到非常困惑,因为几年前,当我还是TA时,我曾经向大学生传授这个概念,所以我给他们错误信息的前景有点令人不安......
这是我给出的问题:
/* What is the output of the following program? */
public class Test {
public boolean equals( Test other ) {
System.out.println( "Inside of Test.equals" );
return false;
}
public static void main( String [] args ) {
Object t1 = new Test();
Object t2 = new Test();
Test t3 = new Test();
Object o1 = new Object();
int count = 0;
System.out.println( count++ );// prints 0
t1.equals( t2 ) ;
System.out.println( count++ );// prints 1
t1.equals( t3 …Run Code Online (Sandbox Code Playgroud) 我经常在不同的地方找到一种平等的方法.它实际上做了什么?重要的是我们必须在每个班级都有这个吗?
public boolean equals(Object obj)
{
if (obj == this)
{
return true;
}
if (obj == null)
{
return false;
}
if (obj instanceof Contact)
{
Contact other = (Contact)obj;
return other.getFirstName().equals(getFirstName()) &&
other.getLastName().equals(getLastName()) &&
other.getHomePhone().equals(getHomePhone()) &&
other.getCellPhone().equals(getCellPhone());
}
else
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud) 在我写完标题之后,我读了这篇SO 帖子,但仍然决定在Java中讨论有关bug的bug实现问题.这是我的正常实施
@Override
public boolean equals(Object o){
if(o == null) return false;
if(o instanceof CompositePk == false) return false;
if(this == o) return true;
CompositePk that = (CompositePk)o;
return new EqualsBuilder().append(this.id, that.id)
.append(this.bucketId, that.bucketId)
.isEquals();
}
Run Code Online (Sandbox Code Playgroud)
使用Apache的EqualsBuilder来完成平凡的事情.比这更容易的是我的Netbean自动生成的equals(o)实现
@Override
public boolean equals(Object obj){
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TemplatesWrapper other = (TemplatesWrapper) obj;
if (this.timeAdded != other.timeAdded && (this.timeAdded == null || !this.timeAdded.equals(other.timeAdded))) {
return false; …Run Code Online (Sandbox Code Playgroud) 我的代码在下面发生了一个奇怪的问题:
RestAPIHeader requestedBy = new RestAPIHeader("X-Requested-By", "test");
// Act
RestAPIRequest req = prepareLoginRequest(USER_NAME, PASSWORD);
// The following returns a list of header objects such that one of them
// is "X-Requested-By: test"
List<RestAPIHeader> headers = req.getAllHeaders();
boolean foundRequestedBy = false;
for (RestAPIHeader h : headers) {
Log.d(LOGTAG, "Header: " + h.toString());
if (requestedBy.equals(h)) {
foundRequestedBy = true;
}
}
// Assert
assertNotNull(req);
// This assertion passes
assertTrue(foundRequestedBy);
// This assertion fails
assertTrue(headers.contains(requestedBy));
Run Code Online (Sandbox Code Playgroud)
困扰我的是,它似乎headers.contains(requestedBy)应该等同foundRequestedBy于此代码(因为这是简单搜索的结果).但是,正如我在评论中提到的那样,它实际上并没有返回相同的值.它似乎似乎contains没有使用equals() …
- 是的,这是一个问题,需要帮助解决作为家庭作业的事情.不,这不是我要求你为我做功课.半个小时前的截止日期; 我确实无法改变我的提交.你只需要相信我的话.继续...
我知道测试对象类型应该是不必要的.当我在寻找有关'instanceof'的详细信息时,我找到了六个线程,人们只回应告诉原始的海报,如果他们必须进行测试以找出他们在处理之前处理的是什么类型的对象,他们就会犯错它.是的,我知道,我很乐意遵循这些惯例.不幸的是,我的教授要求我们覆盖我们定义的类的equals方法,特别是需要一个Object类型参数.如果你看到我的代码,你可能会更好地理解:
public boolean equals(Course other){
if(!(other instanceof Course)){
return false;
} else if(other.name==this.name && other.days==this.days &&
other.start==this.start && other.end==this.end){
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
你可以理解我要去哪里.'other'参数应该是Object类型,但如果我将它保留为Object并使用名称/ days/start/end字段,则该程序是合适的.如果我把它改成课程,当然它可以工作(没有双关语),但这将是一个完全不同的方法.所需的行为是除了Course实例之外的所有对象使该方法返回false,此外,对于Course实例之间的不匹配数据,使其返回false.
对于那些了解Java的人来说,通过看到这样的问题感到沮丧,我感到很遗憾.
我在Java中创建了一个复杂的对象,我正在使用equals方法对它进行比较.
这是可以的,还是首选给对象一个名称或id并比较对象名称/ ID?
为什么要ts.contains(t)返回false,我该如何解决?看看我的代码,请:
class MyList {
private String x;
public MyList (String x) {
this .x = x;
}
public String toString () {
return x;
}
public static void main ( String [] args ) {
List<MyList> ts = new ArrayList<MyList>();
ts.add (new MyList ("one"));
ts.add (new MyList ("two"));
ts.add (new MyList ("three"));
MyList t = new MyList("one");
System.out.println ("Is t in ts? " + ts.contains(t));
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢大家的帮助.SamzSakerz和michaeak的答案都能正常工作.
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public boolean equals(Person p) {
System.out.println("..............");
return p.name.equals(this.name);
}
}
Run Code Online (Sandbox Code Playgroud)
嗨,我正在通过OCJP问答并回答这个问题是 equals方法没有正确覆盖Object.equlas方法.
我认为用名称来覆盖这里是多余的,但是这个问题的答案也是不正确的.
能不能指出我在这里缺少什么概念......
注意:没有选项说覆盖hasCode和equlas与此问题具有相同的参数...
如果政治家的头衔相同,我必须创建一个返回true的equals方法.我如何比较字符串?
这就是我到目前为止尝试写它的方式:
public class Politician implements Priority{
private String name, title;
private int a;
public Politician(String n, String t, int p){
name=n;
title=t;
a=p;
}
public boolean equals(Politician a){
if(title.equals(a.title))
return true;
return false;
}
Run Code Online (Sandbox Code Playgroud)
但是,它总是返回false.即使我测试:
Priority t4= new Politician("Arnie", "Governor", 4);
Politician t5= new Politician("Bill", "Governor", 10);
System.out.println(t5.equals(t4));
System.out.println(t4.equals(t5));
Run Code Online (Sandbox Code Playgroud)
我以前写过equals(),我不知道为什么它不再起作用了
java ×11
equals ×2
object ×2
.net ×1
field ×1
hashcode ×1
inheritance ×1
overriding ×1
performance ×1