Java 是否存在对象的任何内部映射';将哈希代码转换为我们在类中重写的内容

Java 是否存在对象的任何内部映射';将哈希代码转换为我们在类中重写的内容,java,Java,集合关心唯一性,因此在程序中实现集合时,我们必须重写java.lang.Objectequals()和hashCode()方法,这样我们就不会得到重复的集合。引用在JVM的单个和当前实例的上下文中保持其有效性,请记住这一点,我试图以这种方式编写程序。在TestSet.main中(第4-6行)。我试图通过在这些行中使用注释以实用的方式提出我的查询 class TestCase { transient private int x; private int y; public

集合关心唯一性,因此在程序中实现集合时,我们必须重写
java.lang.Object
equals()
hashCode()
方法,这样我们就不会得到重复的集合。引用在JVM的单个和当前实例的上下文中保持其有效性,请记住这一点,我试图以这种方式编写程序。在TestSet.main中(第4-6行)。我试图通过在这些行中使用注释以实用的方式提出我的查询

class TestCase  {
    transient private int x;
    private int y;
    public TestCase(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public boolean equals(Object o) {
        if (o instanceof TestCase && (((TestCase) o).getXValue() == getYValue()))
            return true;
        else
            return false;
    }
    public int hashCode() {
        return x + y;
    }
    public int getXValue() {
        return x;
    }
    public int getYValue() {
        return y;
    }
}

class TestSet {
    public static void main(String[] args) {
        TestCase tc1 = new TestCase(4, 8);
        TestCase tc2 = new TestCase(4, 8);
        Set<TestCase> set = new HashSet<TestCase>();
        set.add(tc1);//succeeds
        set.add(tc2);//succeeds
        System.out.println(set.add(tc2));//fails and gives us false.
        tc2 = new TestCase(4, 8);
        System.out.println(set.add(tc2));//succeeds and gives us true?
        System.out.println(set.size());
        System.out.println(set.contains(tc1));
        System.out.println(set.contains(tc2));
    }
}
类测试用例{
瞬时私有int x;
私营企业;
公共测试用例(intx,inty){
这个.x=x;
这个。y=y;
}
公共布尔等于(对象o){
if(o TestCase的instanceof&((TestCase)o).getXValue()==getYValue())
返回true;
其他的
返回false;
}
公共int hashCode(){
返回x+y;
}
public int getXValue(){
返回x;
}
public int getYValue(){
返回y;
}
}
类测试集{
公共静态void main(字符串[]args){
testcasetc1=新的TestCase(4,8);
testcasetc2=新的TestCase(4,8);
Set=newhashset();
set.add(tc1);//成功
set.add(tc2);//成功
System.out.println(set.add(tc2));//失败并给出false。
tc2=新的测试用例(4,8);
System.out.println(set.add(tc2));//成功并给出true?
System.out.println(set.size());
System.out.println(set.contains(tc1));
System.out.println(set.contains(tc2));
}
}

您的equals方法中有一个输入错误:您正在将一个元素的
x
与另一个元素的
y
进行比较。这几乎毫无意义;你应该同时比较x和y

您应该将
equals
实现为

return o instanceof TestCase
   && ((TestCase) o).getXValue() == getXValue()
   && ((TestCase) o).getYValue() == getYValue();

第二个
.add(tc2)
返回
false
的原因是
HashSet
的实现使用
=
检查作为优化,而这恰好捕获了特定情况。这不会改变
.equals
方法的中断。

equals
hashCode
必须遵守的规则是:如果两个对象相等,则它们的哈希代码必须相同

请注意,这并不意味着相反:如果两个对象具有相同的哈希代码,则不一定意味着两个对象相等


您的代码违反了此规则,因此当您将这两个对象放入
哈希集中时,会得到不可预测的结果。首先,您最好完全修复或删除equals方法。您的情况与hashCode方法的工作方式无关,我将在下面解释它的工作方式:

// Set is looking for tc2 and finds object with same ref, because of previous set.add(tc2);
System.out.println(set.add(tc2));//fails and gives us false.

// You create new object with new reference.
tc2 = new TestCase(4, 8);

// Yes, because you changed tc2 variable and assigned new reference to it.
System.out.println(set.add(tc2));//succeeds and gives us true?

您的
equals()
是错误的,因为您正在将
this.x
o.y
(苹果对桔子)进行比较。您需要比较
x
y
。使用适当的覆盖不是我的意图,而是使用合法的,但是感谢louis让我知道HashSet类使用的实现类型。我建议在检查内部数据之前添加引用检查。类似这样的返回(o==this)| |(o TestCase&((TestCase)o的实例)。getXValue()==getXValue()&((TestCase)o)。getYValue()==getYValue());这总是有助于加快速度;)@格沃加鲁特云岩……你为什么这么说?正如我已经提到的,
HashSet
为您执行
=
检查。第二次这样做是没有意义的;我希望这会损害成绩,而不是帮助。以防万一其他班级不会这样做。