【问题标题】:hashset return false when should return truehashset 什么时候返回 false 应该返回 true
【发布时间】:2014-04-09 15:25:52
【问题描述】:

我正在为迷宫编程,但遇到了一些问题。

我有:

HashSet<State> closedList = HashSet<State>(); //it hold State objects

我的State 类如下所示:

public class State implements Comparable<State>{
private double f;
private double g;
private String state; 
private State prev;
.
.
.

closedList.add(state);
closedList().contains(state); // this equals true

但是当我这样做时:

State temp = State(0,0,"");
temp.setStateName(state.getStateName());

closedList().contains(temp); // this equals false

我在State中实现了equalshashCode

@Override
public int hashCode(){
    return state.hashCode();
}

@Override
public boolean equals(Object object){
    if(this.state == object){
        return true;
    }
    if(object == null || object.getClass() != this.getClass()){
        return false;
    }
    return false;
}

【问题讨论】:

  • 你期待有什么不同吗?再次仔细检查您的代码...(提示:.equals()
  • 我很抱歉,我对 java 很菜鸟,equals 中的问题是什么?
  • 除非this.state == this == object,否则您的equals 方法毫无意义。
  • 很简单:您希望两个新对象以相同的状态被初始化以指向相同的引用 (==);但这种情况并非如此。这就是.equals() 的用途
  • 在我看来,最好的学习方式是阅读开源代码。番石榴 javadocs : docs.guava-libraries.googlecode.com/git/javadoc/com/google/…, java.lang.Object)

标签: java hashset


【解决方案1】:
closedList().contains(state); // this equals true

这是一条红鲱鱼,它只返回 true,因为 HashSet 在调用 equals 之前会检查 ==

你应该尝试的是这样的:

State temp = new State(0, 0, "");
System.out.println(temp.equals(temp));

你会发现这返回 false。这是为什么?好吧,让我们按照逻辑进行。

首先,你有这张支票:

if(this.state == object){
    return true;
}

如果您真的打算这样,这意味着您期望 equals 以字符串 state 作为参数被调用,如下所示:

temp.equals(temp.getStateName())

(并且上面的调用会返回 true。)这是不正确的,人们不会期望 equals 为不相关的类返回 true(并且就 equals 合约而言,这是不是 对称的情况)。我认为这是无意的,就像一个错误。在编写代码时,您应该更仔细地考虑代码在做什么。

你也应该是comparing Strings with equals, not ==

然后是这个构造:

if(object == null || object.getClass() != this.getClass()){
    return false;
}
return false;

这是没有意义的,因为它首先在逻辑上意味着 this,无论哪种方式都返回 false:

if(object == null || object.getClass() != this.getClass()){
    return false;
} else {
    return false;
}

而且,第二,结合前面的检查,它不是特别合乎逻辑:

if(this.state == object)
    return true;
if(object.getClass() != this.getClass())
    return false;

如果object== 到字符串,则返回true,但如果object 的类不是State,则返回false。这些是相互排斥的。

所以你写的 equals 实现不起作用。与您的hashCode 匹配的正确equals 是这样的:

@Override
public boolean equals(Object object){
    if(object == null || object.getClass() != this.getClass()){
        return false;
    }

    State other = (State)object;
    return this.state.equals(other.state);
}

首先检查该对象不为空且其类为State(您的部分正确),然后检查state 成员是否等于另一个对象的state 成员。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 2021-09-04
    • 2012-08-08
    • 2018-11-09
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多