Java hashCode()方法用于以下情况:当两个集合至少有一个共同元素时,它们是否相等?

Java hashCode()方法用于以下情况:当两个集合至少有一个共同元素时,它们是否相等?,java,equals,hashcode,Java,Equals,Hashcode,我目前面临一个场景,我有一个字符串元组(大小为2),如果两个元组至少有一个公共元素,那么它们应该被认为是相等的。我有以下班级来实现这个想法: public class MyTuple { private List<String> list = Arrays.asList(new String[2]); public List<String> getList() { return list; } public vo

我目前面临一个场景,我有一个字符串元组(大小为2),如果两个元组至少有一个公共元素,那么它们应该被认为是相等的。我有以下班级来实现这个想法:

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;
    }
}
公共类MyTuple
{
private List=Arrays.asList(新字符串[2]);
公共列表getList()
{
退货清单;
}
公共无效集(字符串firstElement、字符串secondElement)
{
list.set(0,第一个元素);
列表.集合(1,第二元素);
}
@凌驾
公共布尔等于(对象其他)
{
if(MyTuple的其他实例){
return!Collections.disjoint(this.list,((MyTuple)other.getList());
}
返回false;
}
}
但是,根据
hashCode()
合同:

如果根据equals(Object)方法两个对象相等,那么对两个对象中的每一个调用hashCode()方法必须产生相同的整数结果


如何重写我的
hashCode()
方法以不违反合同?

在考虑
hashCode()
之前,我认为您应该首先重新考虑您的
equals()
设计。我认为您无法实现
equals()
并履行所需的契约——特别是关于传递性的契约

发件人:

equals方法在非null上实现等价关系 对象引用:

  • 它是自反的:对于任何非空参考值x,x等于(x) 应该返回true

  • 它是对称的:对于任何非空的引用值 x和y,x.equals(y)应返回true当且仅当y.equals(x) 返回true

  • 它是可传递的:对于任何非空引用值x, y、 z,如果x.equals(y)返回true,y.equals(z)返回true, 那么x.equals(z)应该返回true

  • 这是一致的:对任何人来说 非空引用值x和y,x.equals(y)的多次调用 一致返回true或一致返回false,前提是 对象上的相等比较中使用的信息将被修改

  • 为了 任何非空引用值x,x.equals(null)都应返回false
为什么??我可以构造您的
MyTuple
的三个对象:

  • A={x1,x2}
  • B={x2,x3}
  • C={x3,x4}
其中
x1
x2
x3
x4
都是不同的。现在我有

  • A.equals(B)返回true
  • B.equals(C)返回true
  • C.equals(A)返回false
它们违反了及物性的约定

我认为你应该考虑使用你自己的另一个关系(也许是代码> PudialSub()),这样你就不必遵守合同了。但是 您也不能使用像
equals()
这样的方法并期望
MyTuple
工作,
例如,在
HashMap
HashSet
等中,不需要,因为
MyTuple
永远不能是集合中的键。为什么不呢?我正在使用Spark,MyTuple将是成对RDD中的键。为hashCode()返回一个常量。在任何使用hashcode的集合中使用MyTuple肯定会影响性能,但使用“动态”相等规则是满足契约的唯一方法。我对此投了赞成票,因为它在实践中起作用。然而,正如@leeyuiwah所提到的,我在equals()方法中违反了另一个约定。不幸的是,partialEquals()没有帮助,因为我需要在Spark中对MyTuple执行“ByKey”操作作为密钥。所有这些操作都依赖于equals()和hasCode()。显然,我需要重新考虑一下。谢谢。@ Tkh——您可以考虑在代码< Mytuple < /代码>中进行规范化——通过在<代码>列表中排序元素(按顺序),因此,如果您有<代码> {x1,x2} /COD>和<代码> {x2,x1} /COD>,它们总是规范化为<代码> {x1,x2}(假设“代码> x1按顺序排列”)。完成此操作后,您可以拥有一个
equals()
(以及
hashCode()
),它在排序后始终在
列表上运行。@TKh-(继续…)不知道您的确切应用场景。这种规范化的想法可能对你有用,也可能不管用。