hashset返回false时应该返回true

时间:2014-04-09 15:25:53

标签: java hashset

我编写了一个迷宫,我遇到了一些问题。

我有:

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

我已在equals中实施hashCodeState

@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;
}

1 个答案:

答案 0 :(得分: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的情况。)这是不正确的,人们不会期望等于对不相关的类返回true(并且就等于合同而言,它是&#39; s这不是对称)。我认为这是无意的,就像一个错误。在编写代码时,您应该更仔细地考虑代码的作用。

此外,您应该comparing Strings with equals, not ==

然后有这个结构:

if(object == null || object.getClass() != this.getClass()){
    return false;
}
return 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==为String,则返回true;如果object的类不是State,则返回false。这些是相互排斥的。

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

@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成员是否等于其他对象&#39; s { {1}}成员。