当前位置: 首页 > 知识库问答 >
问题:

为什么这两个简单的物体不相等?

长孙昀
2023-03-14

我在学校上课:

public class School {

    private String name;
    private int id;
    private boolean isOpen;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public boolean isOpen() {
        return isOpen;
    }
    public void setOpen(boolean isOpen) {
        this.isOpen = isOpen;
    }
}

然后我创建了School的两个实例,并比较了两个实例的相等性:

public static void main(String[] args) {
        //school1
        School school1 = new School();
        school1.setId(1);
        school1.setName("schoolOne");

        //school2
        School school2 = new School();
        school2.setId(1);
        school2.setName("schoolOne");

            //result is false , why?
        System.out.println("school1 == school2 ? " + school1.equals(school2));

    }

即使我设置了相同的idnameSchool 1

共有3个答案

微生俊
2023-03-14

尽管我给school1设置了相同的id和名称

您需要在School类中覆盖equals()方法。否则为Object类中的默认方法实现。

请参阅默认实现

public boolean More ...equals(Object obj) {
        return (this == obj);
    }

在您的情况下,它是false,因为您正在创建两个对象。

对于解决方案,首选阅读。

夹谷沛
2023-03-14

想象一下双胞胎(在现实生活中),即使他们有相同的外表、相同的年龄和相同的名字,他们是平等的吗?不,他们不是,他们是两个不同的“例子”。

在Java也是一样。两个不同的实例不能(隐式地)相等,因为它们各自独立存在于各自的内存部分。

但是,如果您想像那样比较它们,您可以ovveride equals()方法,或者您可以创建自己的新方法进行比较。

宇文峰
2023-03-14

必须重写equals(Object)方法:

把这个放在你的学校课堂上:

@Override
public boolean equals(Object other) {
    if (other == this) return true;
    if (other == null || !(other instanceof School)) return false;
    School school = (School) other;
    if (school.id != this.id) return false;
    if (!(school.name.equals(this.name))) return false;
    if (school.isOpen != this.isOpen) return false;
    if (!(school.hashCode().equals(this.hashCode()))) return false;
    return true;
}

如果要进行此操作,还应该重写hashCode()方法。

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + (int) id;
    result = prime * result + (name != null ? name.hashCode() : 0);
    result = prime * result + (isOpen ? 0 : 1);
    return result;
}

我相信这是重写hashCode()的最佳解释。

这个答案是由dmeister为以下帖子发布的: SO:哈希代码实现。

我一直在引用它,在Eclipse中为给定类生成hashCode()方法时,似乎使用了这个函数性。

Josh Bloch在第8项中的“有效Java”中提出了几乎所有情况下的合理良好实现。最好的办法是在那里查阅,因为作者在那里解释了为什么这种方法是好的。

一个简短的版本:

>

  • 创建一个int结果并指定一个非零值。

    对于在equals-method中测试的每个字段,通过以下方式计算哈希代码c:

    • 如果字段f是布尔值:计算(f?0:1)

    将哈希值c与结果相结合:

    result=37*结果c

    返回结果

    这应该导致哈希值在大多数使用情况下的适当分布。

  •  类似资料:
    • 为什么它不打印“processTextPosition:ContainsKey”?

    • 在这个打印从1到10000000的所有数字、Haskell版本和C版本的简单程序中,为什么Haskell版本如此缓慢,以及哪些命令有助于学习如何提高Haskell程序的性能? 下面是一份报告,包含重现我激动人心的事件所需的所有细节,制作报告时会打印出来源,包括Makefile的来源:

    • 问题内容: 似乎以下代码应返回true,但返回false。 这有什么意义? 问题答案: 常规()和严格()相等之间的唯一区别是,严格相等运算符禁用类型转换。由于已经在比较两个相同类型的变量,因此使用的相等运算符的类型无关紧要。 不管您使用常规相等还是严格相等,对象比较仅 在您比较相同的精确对象时得出 。 也就是说,给定,,,但。 两个不同的对象(即使它们都具有零或相同的精确属性)也永远不会相等地进

    • 问题内容: 考虑以下两种情况: (转到Playground链接) 第二个打印9.120000000000001,实际上很好 但是,为什么第一行打印9.12,但末尾没有…01?Go是否会将两个未类型化的常数相乘,并在编译时将它们简单地替换为9.12文字? 问题答案: 根据规格: 常量表达式总是精确地求值;中间值和常量本身可能需要比该语言中任何预声明类型支持的精度大得多的精度。 以来 是一个常数表达式

    • 我正在学习使用stl向量,这是奇怪的,这个程序不能工作。这有什么问题?如果我想用Vector实现同样的功能,应该怎么做呢?

    • 问题内容: 很简单的一行: 失败与: 而扩展为: 工作良好。 问题答案: 您使用错误。使用这种方式: 通用形式为: