简体   繁体   English

哈希集返回false何时应返回true

[英]hashset return false when should return true

I'm programming a Maze and I have some problems. 我正在编程迷宫,但遇到一些问题。

I have: 我有:

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

My State class look like this: 我的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

but when I do this: 但是当我这样做时:

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

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

I have implemented equals and hashCode in State : 我已经在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;
}
closedList().contains(state); // this equals true

This is a red herring, it only returns true because HashSet checks with == before it makes a call to equals . 这是一条红色鲱鱼,它只返回true,因为HashSet在调用equals之前会先使用==进行检查。

What you should try is something like this: 您应该尝试的是这样的:

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

And you will find this returns false. 您将发现此返回错误。 Why is that? 这是为什么? Well let's follow the logic through. 好吧,让我们遵循逻辑。

First, you have this check: 首先,您有以下检查:

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

If you really intended this to be the way it is, it means you were expecting equals to be called with the String state as the argument, like this: 如果您确实希望这样做,则意味着您希望以String state作为参数来调用equals ,如下所示:

temp.equals(temp.getStateName())

(And it's the case the above call would return true.) This is incorrect, one would not expect equals to return true for unrelated classes (and in terms of the equals contract, it's the case this is not symmetric ). (这种情况是上面的调用返回true的情况。)这是不正确的,我们不希望equals对于不相关的类返回true(就equals契约而言,这是不对称的 )。 I assume this is unintended and just like a mistake. 我认为这是意外的,就像一个错误。 You should think more carefully about what your code is doing when you are writing it. 您在编写代码时应该仔细考虑代码的作用。

Also you should be comparing Strings with equals , not == . 另外,您应该将字符串与equals而不是==进行比较

Then there is this construct: 然后是这个构造:

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

This is pointless because first what it implies logically is this, returning false either way: 这毫无意义,因为首先从逻辑上讲这是隐含的,无论哪种方式返回false:

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

And, second, combined with the earlier check it is not particularly logical: 其次,与较早的检查结合起来并不是特别合乎逻辑:

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

This is returning true if object is == to a String but returning false if object 's class is not State. 如果object ==返回字符串,则返回true;如果object的类不是State,则返回false。 These are mutually exclusive. 这些是互斥的。

So the equals implementation you wrote doesn't work. 因此,您编写的equals实现无效。 The correct equals to match your hashCode is like this: 正确的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);
}

First check that the object is not null and that its class is State (you had that part right), then check that the state member is equal to the other object's state member. 首先检查对象是否不为空,并且其类为State (您拥有该部分的权利),然后检查state成员是否等于另一个对象的state成员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM