Java: Use hashCode() inside of equals() for convenience?

烈酒焚心 提交于 2019-11-27 21:18:17

In general, it's not at all safe to compare the hashCode() instead of using equals(). When equals() returns false, hashCode() may return the same value, per the contract of hashCode().

Very bad! HashCode equality does not mean that equals returns true. The contract is that two objects that are equal must have the same hashCode. But it DOES NOT state the two objects with the same HashCode must be equal.

As all other answers state this is bad practice. However, one situation where you might want to refer to the hash code within the equals method is in cases where you have an immutable object and have cached the hash code previously. This allows you to perform a cheap inexact comparison before performing a full comparison. For example:

public class MyImmutable {
    private final String a;
    private final String b;
    private final int c;

    private int hashCode;

    public MyImmutable(String a, String b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

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

        MyImmutable that = (MyImmutable) o;

        // Compare cached hashCodes first before performing more expensive comparison.
        return hashCode == that.hashCode() && c == that.c && !(a != null ? !a.equals(that.a) : that.a != null) && !(b != null ? !b.equals(that.b) : that.b != null);
    }

    @Override
    public int hashCode() {
        if (hashCode == 0) {
            // hashCode not cached, or it was computed as 0 (we recalculate it in this case).
            hashCode = a != null ? a.hashCode() : 0;
            hashCode = 31 * hashCode + (b != null ? b.hashCode() : 0);
            hashCode = 31 * hashCode + c;
        }

        return hashCode;
    }
}

This is not OK. Hashcodes, by their very nature, are not guaranteed to be unique.

Bad practice? More than that, it's completely wrong. Two un-equal objects can return the same hash code. Do not do this.

Here is the contract, copied from the Object specification [JavaSE6]:

It is not required that if two objects are unequal according to the equals(Ob- ject) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

To answer your question, No. Not a good idea.

Raedwald

As Ryan Stewart says, your code as written is faulty.

A situation in which it might be useful to use the hash-code of your objects in equals() is when your object caches the hash codes, and determining equality is portentially expensive. In that case you might use equality of the cached hash codes as one of the early necesssary-but-not-sufficient checks for equality, to return false fast for most pairs of objects that are not equals().

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