2

我对这些概念很陌生,而且用户很天真,所以请原谅我下面的问题,但是

我想了解java中集合的基本概念

我做了以下课程

package com.vish;

public class HashSetDemo {
    private int age;

    public HashSetDemo(int age) {
        this.age = age;
    }
}

现在,我在下面的课程中描述了集合框架

package com.vish;

import java.util.HashSet;

public class HashSetDemo1 {
    public static void main(String args[]) {

        HashSetDemo hsd = new HashSetDemo(23);
        HashSetDemo hsd1 = new HashSetDemo(24);
        HashSet<HashSetDemo> hashset = new HashSet<HashSetDemo>();
        hashset.add(hsd);
        hashset.add(hsd1);
        System.out.println(hashset.size());
        System.out.println(hashset.contains(hsd));
        System.out.println(hashset.contains(new HashSetDemo(23)));
    }
}

现在的结果如下

2
true
false

为什么最后一个是假的,当它具有相同的对象引用时

谢谢

4

7 回答 7

2

为什么最后一个是假的,当它具有相同的对象引用时

它没有。您创建了一个对象,该对象恰好具有相同的age.

这就像要求建筑商为您建造两栋带 5 间卧室的房子。是的,它们看起来一样——但它们是不同的房子,有不同的地址。

现在HashSet实际上不用于相等的引用- 它检查相等的对象hashCode- 通过andequals方法确定相等性。默认情况下,这会检查参考身份,但不是必须的。因此,如果您覆盖equalshashCode确定相等性只是您的age值,那么它将认为您的新对象等于旧对象。

public final class HashSetDemo {
    private final int age;

    public HashSetDemo(int age) {
        this.age = age;
    }

    @Override public int hashCode() {
        return age;
    }

    @Override public boolean equals(Object other) {
        if (!(other instanceof HashSetDemo)) {
           return false;
        }
        HashSetDemo otherDemo = (HashSetDemo) other;
        return age == otherDemo.age;
    }
}
于 2013-05-31T06:58:00.183 回答
1

因为你还没有equals()在你的HashSetDemo课堂上实现。如果你不这样做,那么 java 就无法弄清楚如何判断两个对象是否相等。不过它确实有一个默认实现,默认实现是问:“这两个对象是同一个引用吗?”

由于您正在显式创建一个新的HashSetDemo,Java 使用默认值equals()并说,“不,这些不是同一个实例HashSetDemo

于 2013-05-31T06:58:33.933 回答
0

为什么最后一个是假的,当它具有相同的对象引用时

即使对象完全相同,它们也不是相同的对象。这就像把一辆全新的自行车放在车库里,得到另一辆与另一辆完全相同的全新自行车,然后询问车库是否包含第二辆自行车。当然,自行车可能是相同的,但它们并不相同

顺便说一句,好问题。

于 2013-05-31T06:58:26.693 回答
0

您需要在 HashSetDemo 中覆盖 equals() 和 hashCode()。这告诉您的程序如何确定 2 个单独的实例是否相等。如果你不这样做,你的程序将退回到默认实现,它只检查对象引用。在您的第三行中,对象是等价的,但 Java 不知道 - 它只知道它是一个不同的引用。

于 2013-05-31T06:59:45.743 回答
0

在您创建的最后一种情况下new Object new HashSetDemo(23),它将存储在java heap memory. 与其他两个对象相比,它是不同的hsd and hsd1

于 2013-05-31T07:01:46.160 回答
0

因为您没有为您的类提供自定义的 equals 和 hashCode 方法。您的类使用 Object 提供的实现。

如果您覆盖 equals to bereturn this.age == ((HashSetDemo)other).age并覆盖 hashCode 以返回从年龄派生的哈希值,那么您对 ​​hashset.contains 的最后一次调用将返回 True。

于 2013-05-31T06:57:09.263 回答
0

它不是同一个参考。在第二种情况下,您正在创建 , 的新实例HashSetDemo,并且该实例在内存中具有不同的地址。

HashSet正在使用默认比较器进行搜索,并且比较对象的实例,而不是它们的内容。

于 2013-05-31T06:57:34.487 回答