1

I was make some code and found that objects ar eno equals - it is trivial question but not understand how default equals works.

class A {
    String id;
    public A(String id) {
        this.id = id;
    }

    public static void main(String args[])
    {
        A a = new A("1");
        A b = new A("1");
        System.out.println(a.id);
        System.out.println(b.id);
        System.out.println(a.equals(b));
    }
}

Result is:

1
1
false

But I want to have a.equals(b) == true why it is false?

Chameleon
  • 9,722
  • 16
  • 65
  • 127

4 Answers4

4

Your class currently extends only Object class and in Object class equals method looks like this

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

What you need is to override this method, for example like this

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    A other = (A) obj;
    if (id == other.id)
        return true;
    if (id == null)
        return false;
    if (other.id == null)
        return false;
    if (!this.id.equals(other.id))
        return false;
    return true;
}

Also when you override equals you probably should override hashCode method, but this is not subject of your question. You can read more about it here.

Community
  • 1
  • 1
Pshemo
  • 122,468
  • 25
  • 185
  • 269
4

If you don't override equals() on the object, you are comparing two different memory references. So override equals() to compare the id fields.

pwfixed
  • 53
  • 5
1

It overrides Object's equals method by default, it checks the "same object" rather than "same content". If you want to have a.equals(b) == true, you should override it:

@Override
public boolean equals (Object obj) {
    if (obj instanceof A) {
        A a = (A) obj;
        if (id == null) {
            return a.id == null;
        } else {
            return id.equals(a.id);
        }
    }
    return false;
}

----- EDITED -----

shuangwhywhy
  • 5,475
  • 2
  • 18
  • 28
  • Good but code is not clear (not for me) - improve code style you could be good but not readable. – Chameleon Feb 12 '13 at 01:57
  • Some bugs in code since null of obj + null of this.is or obj.id. – Chameleon Feb 12 '13 at 02:11
  • Good but still code style is ugly (could be faster too) - it is good advice for you the most important in writing large program is readability not code compression - it is major factor of quality. You focus on compression of code (side effect is complication and hard to understand code or review it) change it since it blocks development. – Chameleon Feb 12 '13 at 11:02
  • Some example `!obj.getClass().equals(A.class)` better is simple `obj.getClass() != A.getClass())` (who know what do equals, why to check it, why negate result). – Chameleon Feb 12 '13 at 11:02
  • Some redundancy `if (id == null) return id == ((A) obj).id;` == `if (id == null) return id == obj.id;` better is `if (id == null && obj.id == null) return true; else return false;` more clear *not need understand transition* (if id == null so id == obj.id mean obj.id == null faster reading/review - avoid logic puzzles as much as possible. Maybe I help you little. – Chameleon Feb 12 '13 at 11:03
  • @Chameleon, `obj.id` is wrong. `obj` is type of `Object`, not `A`. You have to cast it. – shuangwhywhy Feb 12 '13 at 13:02
  • @Chameleon, Also, instead of compare their `Class`, it is better to use `instanceof` keyword. – shuangwhywhy Feb 12 '13 at 13:28
0

you should rewrite an equals() method for your code, as you would a toString() method.