English 中文(简体)
HashSet.contains没有按原样行事。 法典和平等
原标题:HashSet.contains does not behave as expected with hashCode and equals
  • 时间:2011-10-20 11:40:22
  •  标签:
  • java
  • hashset

我有一个叫MyClass的班子:

public class MyClass extends abstractClass implements
        someInterface {

    Set<VNode> relation_;
    Set<VNode> x_;
    Set<VNode> y_;


     @Override
    public boolean equals(Object obj) {

        if (!super.equals(obj)) {
            return false;
        }

        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof MyClass)) {
            return false;
        }
        MyClass other = (MyClass) obj;

        if (relation_ == null) {
            if (other.relation_ != null) {
                return false;
            }
        } else if (!relation_.equals(other.relation_)) {
            return false;
        }
        if (x_ == null) {
            if (other.x_ != null) {
                return false;
            }
        } else if (!x_.equals(other.x_)) {
            return false;
        }
        if (y_ == null) {
            if (other.y_ != null) {
                return false;
            }
        } else if (!y_.equals(other.y_)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int res = new HashCodeBuilder(17, 37).append(relation_).append(x_)
                .append(y_).append(getWeight()).toHashCode();

        return res;
    }
}

抽象的类别如下:

public abstract class abstractClass {

    double weight_;


    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof abstractClass)) {
            return false;
        }
        abstractClass other = (abstractClass) obj;
        if (Double.doubleToLongBits(weight_) != Double
                .doubleToLongBits(other.weight_)) {
            return false;
        }
        return true;
    }

    public double getWeight() {
        return weight_;
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        long temp;
        temp = Double.doubleToLongBits(weight_);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

}

Now, if I have HashSet<MyClass> s1 and an MyClass i1, even if s1 has an element s1i whith s1i.equals(i1)=true and s1i.hashCode()=i1.hashCode(), s1.contains(i1) gives me false.

Any explanations?

Other classes:

public class VNode {

    Mention mention_;


    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof VNode)) {
            return false;
        }
        VNode other = (VNode) obj;
        if (mention_ == null) {
            if (other.mention_ != null) {
                return false;
            }
        } else if (!mention_.equals(other.mention_)) {
            return false;
        }
        return true;
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((mention_ == null) ? 0 : mention_.hashCode());
        return result;
    }



}




public class Mention extends Range {


    private final int                           id_;


    public Mention(final int start, final int end) {
        super(start, end);

        id_ = getNextMentionID();
    }

}





public class Range {


    private final int start_;

    private final int end_;

    /**
     * Contr.
     * 
     * @param start
     * @param end
     */
    public Range(final int start, final int end) {
        start_ = start;
        end_ = end;
    }



    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof Range)) {
            return false;
        }
        Range other = (Range) obj;
        if (end_ != other.end_) {
            return false;
        }
        if (start_ != other.start_) {
            return false;
        }
        return true;
    }



    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + end_;
        result = prime * result + start_;
        return result;
    }



}
问题回答

你们平等的方法根本无法读懂。 由于你正在使用HashCodeBuilder,为什么不使用平等者?

a)

public boolean equals(Object obj){
    if(obj == null || obj.getClass()!=getClass()){
        return false;
    }
    MyClass other = (MyClass) obj;
    return new EqualsBuilder()
      // check parent properties first
      .append(this.getWeight(), other.getWeight())
      .append(this.relation_, other.relation_)
      .append(this.x_, other.x_)
      .append(this.y_, other.y_)
      .isEquals();
}

b)

public boolean equals(Object obj){
    // delegate to parent equals first
    if(!super.equals(obj)){
        return false;
    }
    MyClass other = (MyClass) obj;
    return new EqualsBuilder()
      .append(this.relation_, other.relation_)
      .append(this.x_, other.x_)
      .append(this.y_, other.y_)
      .isEquals();
}

每一类别在计算等值和散列码时,只应涉及自己的变量。 因此,在你的MyClass中,你不应打上getWala(>,而应使用超级类别中的散列代码。 同你一样,还有<条码>等。 在这种情况下,效果将相同。

public int hashCode() {
    int res = new HashCodeBuilder(super.hashcode(), 37).append(relation_).append(x_)
            .append(y_);

    return res;
}

这意味着对基类的任何可能影响到同异和散射法的任何改动都仅限于该类,而无需更新子类。

(实际上不是答案,更是意见,而是评论的太大)





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签