Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<blockquote> <p>what are best practices to implement equals, semantically, not technically.</p> </blockquote> <p>In Java the <code>equals</code> method really should be considered to be <a href="http://today.java.net/pub/a/today/2006/07/27/defining-object-identity.html" rel="nofollow noreferrer">"identity equals"</a> because of how it integrates with <code>Collection</code> and <code>Map</code> implementations. Consider the following:</p> <pre><code> public class Foo() { int id; String stuff; } Foo foo1 = new Foo(10, "stuff"); fooSet.add(foo1); ... Foo foo2 = new Foo(10, "other stuff"); fooSet.add(foo2); </code></pre> <p>If <code>Foo</code> identity is the <code>id</code> field then the 2nd <code>fooSet.add</code> should <em>not</em> add another element to the <code>Set</code> but should replace the first one since they have the same <code>id</code>. If you define <code>Foo.equals</code> (and hashCode) method to include <em>both</em> the <code>id</code> and the <code>stuff</code> fields then this will be broken and the <code>Set</code> may contain 2 references to the object with the same id field.</p> <p>If you are not storing your objects in a <code>Collection</code> (or <code>Map</code>) then you don't have to define the <code>equals</code> method this way, however it is considered by many to be bad form. If in the future you <em>do</em> store it in a <code>Collection</code> then things will be break.</p> <p>If I <em>need</em> to test for equality of all fields, I tend to write another method. Something like <code>equalsAllFields(Object obj)</code> or some such.</p> <p>Then you would do something like:</p> <pre><code>assertTrue(obj1.equalsAllFields(obj2)); </code></pre> <p>In addition, a proper practice is to <em>not</em> define <code>equals</code> methods which take into account mutable fields. The problem also gets difficult when we start talking about class hierarchies. If a child object defines <code>equals</code> as a combination of its local fields <em>and</em> the base class <code>equals</code> then its symmetry has been violated:</p> <pre><code> Point p = new Point(1, 2); // ColoredPoint extends Point ColoredPoint c = new ColoredPoint(1, 2, Color.RED); // this is true because both points are at the location 1, 2 assertTrue(p.equals(c)); // however, this would return false because the Point p does not have a color assertFalse(c.equals(p)); </code></pre> <p>Some more reading I would highly recommend is the "Pitfall #3: Defining equals in terms of mutable fields" section in this great page:</p> <blockquote> <p><a href="http://www.artima.com/lejava/articles/equality.html" rel="nofollow noreferrer">How to Write an Equality Method in Java</a> </p> </blockquote> <p>Some additional links:</p> <ul> <li><a href="http://tutorials.jenkov.com/java-collections/hashcode-equals.html" rel="nofollow noreferrer">Implementing hashCode() and equals()</a></li> <li><a href="http://gracelang.org/applications/2011/02/07/values-equals-and-hashcodes/" rel="nofollow noreferrer">Graceful Blog - Values, Equals, and Hashcodes</a></li> </ul> <p>Oh, and just for posterity, regardless of what fields you choose to compare to determine equality, you need to use the same fields in the <code>hashCode</code> calculation. <code>equals</code> and <code>hashCode</code> must be symmetric. If two objects are equals, they <em>must</em> have the same hash-code. The opposite is not necessarily true.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload