1

Consider:

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");
        }
    }
}

Why does this output "False"? If it is by default in Java that "all objects are not equal even if they have same values" then how can I "persuade" Java that these two objects actually are equal?

Okay, even if two dogs have same name, height, weight one could be Dalmatian and the other one pit bull, and even if they are the same "race", in nature, they can always be different from one another.

PS: I understand that by saying if (one==two) {} we are comparing if they both refer to the same object on the heap, .equals on string's compares if they have same characters in the same order.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Krushe
  • 23
  • 8

3 Answers3

7

The equals method by default says "Is this the same object in memory?" unless you override it.

You didn't override it.

The behavior didn't change.

You'll want to add a new method like this

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 brings up a good point - never, ever, ever implment equals without hashCode. Always use the same fields in both.

public int hashCode() {
    int hash = name.hashCode();
    hash = hash * 31 + weight;
    hash = hash * 31 + height;
    return hash;
}
corsiKa
  • 81,495
  • 25
  • 153
  • 204
3

You have to override your equals method in your Dog class. If not you are just comparing if those objects are the same instance in memory.

Here is an implementation of how to do this:

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;

    }
}
Juan Carlos Mendoza
  • 5,736
  • 7
  • 25
  • 50
3

Any IDE allows you to generate a hashcode and equals in an automatic way as getters and setters.

In your case without hashcode and equals, you will get false, because the objects cannot being at the same memory location.

Your (working) example below:

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");
        }
    }
}

Result:

Enter image description here

To generate hashCode and equals in automatic way in Eclipse:

Right click in your class and:

Enter image description here

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Frank
  • 873
  • 1
  • 7
  • 17
  • I vaguely understand what you are trying to say, but I don't (yet) understand this code implementation. In every case, thank you! – Krushe Sep 11 '17 at 15:16
  • I didnt write any rows of code , i let eclipse do it for me , anyway when you call 'one.equals(two)' , you are calling the overriden equals , where **this** its the object **one** and **obj** its the object **two** . – Frank Sep 11 '17 at 15:22
  • Thanks for explanation, seems a bit clearer now haha How do you let eclipse do that for you? – Krushe Sep 11 '17 at 15:31
  • answer edited (for eclipse) – Frank Sep 11 '17 at 15:36
  • Just for information , for understanding the real utility of hashcode and equals methods read how they works with **HashSet** for example ;) – Frank Sep 11 '17 at 15:40