【问题标题】:Object reference and object showing different result对象引用和对象显示不同的结果
【发布时间】:2013-05-31 06:55:11
【问题描述】:

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

我正在尝试理解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

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

谢谢

【问题讨论】:

    标签: java collections hashset


    【解决方案1】:

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

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

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

    现在HashSet 实际上不用于相等的引用 - 它检查相等的对象 - 其中相等是通过hashCodeequals 方法确定的。默认情况下,这会检查参考身份,但不是必须的。因此,如果您覆盖 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;
        }
    }
    

    【讨论】:

      【解决方案2】:

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

      由于您明确地创建了一个新的HashSetDemo,Java 使用默认的equals() 并说,“不,这些不是HashSetDemo 的同一个实例”

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            【解决方案5】:

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

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

            顺便说一句,问得好。

            【讨论】:

              【解决方案6】:

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

              【讨论】:

                【解决方案7】:

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

                【讨论】:

                  猜你喜欢
                  • 2023-03-03
                  • 2012-08-13
                  • 2020-01-16
                  • 2016-08-30
                  • 2011-02-06
                  • 1970-01-01
                  • 2018-04-14
                  • 1970-01-01
                  • 2014-11-18
                  相关资源
                  最近更新 更多