How to Write an Equality Method in Java

£可爱£侵袭症+ 提交于 2019-12-10 13:58:31

问题


Consider adding an equality method to the following class of simple points:

public class Point {

    private final int x;
    private final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    // ...
}

// my definition of equals

public boolean equals(Point other) {
  return (this.getX() == other.getX() && this.getY() == other.getY());
}

What's wrong with this method? At first glance, it seems to work OK:

Point p1 = new Point(1, 2);
Point p2 = new Point(1, 2);

Point q = new Point(2, 3);

System.out.println(p1.equals(p2)); // prints true

System.out.println(p1.equals(q)); // prints false

However, trouble starts once you start putting points into a collection:

import java.util.HashSet;

HashSet<Point> coll = new HashSet<Point>();
coll.add(p1);

System.out.println(coll.contains(p2)); // prints false

How can it be that coll does not contain p2, even though p1 was added to it, and p1 and p2 are equal objects?


回答1:


While it is true that you should implement hashCode() when you implement equals(), that is not causing your problem.

That is not the equals() method you are looking for. The equals method must always have the following signature: "public boolean equals(Object object)". Here is some code.

public boolean equals(Object object)
{
  if (object == null)
  {
    return false;
  }

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

  if (object instanceof Point)
  {
    Point point = (Point)object;
    ... now do the comparison.
  }
  else
  {
     return false;
  }
}

The Apache EqualsBuilder class is useful for equals implementations. The link is an older version, but still applicable.

If you liked the Apache EqualsBuilder, you will probably like the Apache HashCodeBuilder class as well.

Edit: updated the equals method example for standard shortcuts.




回答2:


You must implement hashCode() whenever you override equals(). These two work together, and they must give consistent results at all times. Failing to do so produces just the erroneous behaviour you observed.

This is explained in more detail e.g. in Effective Java 2nd Edition, Item 9: Always override hashCode when you override equals.




回答3:


Works well by overriding hashcode !

Always remember : override hashCode when you override equals.

@Override public int hashCode() {
        return (41 * (41 + getX()) + getY());
    }

This is my implementations of hashCode.




回答4:


As per contract on equals() you need to implement hashCode() as well.

From the JavaDoc on equals():

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.




回答5:


In addition to the other answers:

If you are using Eclipse as IDE, you can simply use "Source" --> "Generate hashCode() and equals() to get a basic implementation. Do with that what ever you want.




回答6:


When overriding equals, you also have to override hashCode (in particular, if you are going to use HashSet or HashMap...). A suitable (though not to clever) implementation would be:

int hashCode() {
    return x * 31 + y;
}

Another point (no pun intended): You are not actually overriding the equals(Object) method defined in class Object, but instead are defining a new one. The correct way would be:

boolean equals(Object other) {
    if (other == this) return true;
    else if (!(other instanceof Point)) return false;
    else {
        Point p = (Point)other;
        return x == p.getX() && y == p.getY();
    }
}

Note, that the equals method has a pretty strong contract associated with it, which you are to fulfill.



来源:https://stackoverflow.com/questions/9082892/how-to-write-an-equality-method-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!