【问题标题】:Why does this .equals() code example return "false"? [duplicate]为什么这个 .equals() 代码示例返回“false”? [复制]
【发布时间】:2017-09-11 14:46:23
【问题描述】:

考虑:

class Dog{
    int height;
    int weight;
    String name;
}

public class DogTest {

    public static void main(String[] args) {
        Dog one = new Dog();
        one.height=4;
        one.name="fudo";
        one.weight =2;
        Dog two = new Dog();
        two.height=4;
        two.name="fudo";
        two.weight =2;
        if (one.equals(two)){
            System.out.println("True");
        }
        else{
            System.out.println("False");
        }
    }
}

为什么会输出“False”?如果默认情况下在 Java 中“所有对象都不相等,即使它们具有相同的值”,那么我如何“说服”Java 这两个对象实际上是相等的?

好吧,即使两只狗的名字、身高、体重相同,一只可能是斑点狗,另一只可能是斗牛犬,即使它们是同一个“种族”,从本质上讲,它们总是可以彼此不同。

PS:我知道通过说 if (one==two) {} 我们是在比较它们是否都引用堆上的同一个对象,.equals on string 比较它们是否以相同的顺序具有相同的字符。

【问题讨论】:

  • 如果你不覆盖等于,我会很难工作......
  • @Harald 那不一样。这就是为什么某些字符串 == 可以工作而其他字符串不能工作的原因。

标签: java equals


【解决方案1】:

equals 方法默认显示“这是内存中的同一个对象吗?”除非你覆盖它。

你没有覆盖它。

行为没有改变。

你会想要像这样添加一个新方法

public boolean equals(Object o) {
    if(o instanceof Dog) {
        Dog d = (Dog)(o);
        Dog t = this;
        return t.height == d.height && t.weight == d.weight && t.name.equals(d.name);
    }
    return false;
}

Stephan 提出了一个很好的观点 - 永远永远不会在没有 hashCode 的情况下实现 equals。始终在两者中使用相同的字段。

public int hashCode() {
    int hash = name.hashCode();
    hash = hash * 31 + weight;
    hash = hash * 31 + height;
    return hash;
}

【讨论】:

  • 别忘了也重写 hashCode() 方法。
  • @Stephan 1000% 是的。否则哈希图将完全失败!
【解决方案2】:

你必须在你的 Dog 类中重写你的 equals 方法。如果不是,您只是在比较这些对象是否是内存中的同一个实例。

这里是如何做到这一点的实现:

class Dog{
    int height;
    int weight;
    String name;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Dog)) return false;

        Dog dog = (Dog) o;

        if (height != dog.height) return false;
        if (weight != dog.weight) return false;
        return name != null ? name.equals(dog.name) : dog.name == null;

    }
}

【讨论】:

    【解决方案3】:

    任何 IDE 都允许您以自动方式生成哈希码和 equals 作为 getter 和 setter。

    如果你没有 hashcode 和 equals,你会得到 false,因为对象不能在同一个内存位置。

    您的(工作)示例如下:

    class Dog{
        int height;
        int weight;
        String name;
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + height;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            result = prime * result + weight;
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Dog other = (Dog) obj;
            if (height != other.height)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            if (weight != other.weight)
                return false;
            return true;
        }
    
        public static void main(String[] args) {
            Dog one = new Dog();
            one.height=4;
            one.name="fudo";
            one.weight =2;
            Dog two = new Dog();
            two.height=4;
            two.name="fudo";
            two.weight =2;
            if (one.equals(two)){
                System.out.println("True");
            }
            else{
                System.out.println("False");
            }
        }
    }
    

    结果:

    在Eclipse中自动生成hashCodeequals

    在您的班级中单击鼠标右键,然后:

    【讨论】:

    • 我隐约明白你想说什么,但我(还)不明白这个代码实现。在任何情况下,谢谢!
    • 我没有写任何代码行,我让 eclipse 为我做,无论如何,当你调用 'one.equals(two)' 时,你调用的是覆盖的 equals ,其中 this 它的对象 oneobj 它的对象 two
    • 谢谢你的解释,现在似乎更清楚了哈哈你是如何让eclipse为你做的?
    • 答案已编辑(针对 Eclipse)
    • 仅供参考,了解 hashcode 和 equals 方法的真正用途,例如阅读它们如何与 HashSet 一起工作;)
    猜你喜欢
    • 2012-12-17
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多