以下情况的 hashCode() 方法:两组至少有一个共同元素时相等?

The hashCode() method for the following case: two sets are equal when they have at least one element in common?

我目前面临这样一种情况,我有字符串元组(大小为 2),如果两个元组至少有一个共同元素,则它们应该被视为相等。我有以下 class 实现这个想法:

public class MyTuple
{
    private List<String> list = Arrays.asList(new String[2]);

    public List<String> getList()
    {
        return list;
    }

    public void set(String firstElement, String secondElement)
    {
        list.set(0, firstElement);
        list.set(1, secondElement);
    }

    @Override
    public boolean equals(Object other)
    {
        if (other instanceof MyTuple) {
            return !Collections.disjoint(this.list, ((MyTuple) other).getList());
        }
        return false;
    }
}

然而,根据hashCode()合同:

If two objects are equal according to the equals(Object) method, then calling the hashCode() method on each of the two objects must produce the same integer result.

如何覆盖我的 hashCode() 方法而不违反合同?

在考虑hashCode()之前,我觉得你应该先重新考虑一下你对equals()的设计。我认为您无法实施 equals() 并履行所需的合同——尤其是关于 transitivity

的合同

发件人:Java Doc of Object#equals()

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.

  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.

  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.

  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.

  • For any non-null reference value x, x.equals(null) should return false.

为什么?我可以构造你的三个对象 MyTuple:

  • A = {x1, x2}
  • B = {x2, x3}
  • C = {x3, x4}

其中 x1x2x3x4 都是不同的。现在我有

  • A.equals(B) returns 真
  • B.equals(C) returns 真
  • C.equals(A) returns 错误

而且他们违反了传递性契约。

我认为你应该考虑使用你自己的另一个关系(也许partialEquals())这样你就不必遵守合同。但是之后 你也不能使用像equals()这样的方法并期望MyTuple起作用, 例如,在 HashMapHashSet