Java - How to correctly override equals()
I have my own custom class, MyClass and I want a Set
The id field uniquely identifies each MyClass instance, thus 2 MyClass instances with the same id are to all purposes equal. The HashSet.add() official Java documentation says that:
"More formally, adds the specified element e to this set if this set contains no element e2 such that (e==null ? e2==null : e.equals(e2))."
Well this might lead you to think that you only need to override MyClass.equals(). This will not work, and in fact if you debug you will find that MyClass.equals() is never called. Here's an example:
import java.util.HashSet; import java.util.Set; class MyClass { int id = 0; String value = null; public MyClass(final int id, final String value) { this.id = id; this.value = value; } @Override public boolean equals(final Object e) { final MyClass e2 = (MyClass) e; return (e2.id == id); } } public class Main { /** * @param args */ public static void main(final String[] args) { final Seta = new HashSet (); System.out.println(a.add(new MyClass(0, "Hello"))); System.out.println(a.add(new MyClass(1, "World"))); System.out.println(a.add(new MyClass(0, "World"))); } }
The output being:
true true true
The problem here is that equals() is only called if hashCode() differs. So you need to override both hashCode() and equals().
Here's an example:
import java.util.HashSet; import java.util.Set; class MyClass { int id = 0; String value = null; public MyClass(final int id, final String value) { this.id = id; this.value = value; } @Override public boolean equals(final Object e) { final MyClass e2 = (MyClass) e; return (e2.id == id); } @Override public int hashCode() { return id; } } public class Main { public static void main(final String[] args) { final Seta = new HashSet (); System.out.println(a.add(new MyClass(0, "Hello"))); System.out.println(a.add(new MyClass(1, "World"))); System.out.println(a.add(new MyClass(0, "World"))); } }
Running this will output:
true true false
Which is exactly what we wanted.
Comments
Post a Comment
Comment, motherf*cker