{"id":823,"date":"2010-06-15T11:31:33","date_gmt":"2010-06-15T09:31:33","guid":{"rendered":"http:\/\/raftaman.net\/?p=823"},"modified":"2021-05-15T11:46:40","modified_gmt":"2021-05-15T09:46:40","slug":"implementing-equals-the-right-way","status":"publish","type":"post","link":"https:\/\/possiblelossofprecision.net\/?p=823","title":{"rendered":"Implementing equals() the right way"},"content":{"rendered":"<p>\nAt first sight, implementing <code>equals()<\/code> doesn&#8217;t seem fairly hard. Unfortunately, it turns out that writing a correct equality method is surprisingly difficult:\n<\/p>\n<p>\n<a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/lang\/Object.html#equals%28java.lang.Object%29\">http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/lang\/Object.html<\/a><\/p>\n<blockquote>\n<p>The equals method implements an equivalence relation on non-null object references:<\/p>\n<ul>\n<li>It is <i><strong>reflexive<\/strong><\/i>: for any non-null reference value <code>x<\/code>, <code>x.equals(x)<\/code> should return <code>true<\/code>.<\/li>\n<p><\/p>\n<li>It is <i><strong>symmetric<\/strong><\/i>: for any non-null reference values <code>x<\/code> and <code>y<\/code>, <code>x.equals(y)<\/code> should return <code>true<\/code> if and only if <code>y.equals(x)<\/code> returns <code>true<\/code>.<\/li>\n<p><\/p>\n<li>It is <i><strong>transitive<\/strong><\/i>: for any non-null reference values <code>x<\/code>, <code>y<\/code>, and <code>z<\/code>, if <code>x.equals(y)<\/code> returns <code>true<\/code> and <code>y.equals(z)<\/code> returns <code>true<\/code>, then <code>x.equals(z)<\/code> should return <code>true<\/code>.<\/li>\n<p><\/p>\n<li>It is <i><strong>consistent<\/strong><\/i>: for any non-null reference values <code>x<\/code> and <code>y<\/code>, multiple invocations of <code>x.equals(y)<\/code> consistently return <code>true<\/code> or consistently return <code>false<\/code>, provided no information used in <code>equals<\/code> comparisons on the objects is modified.<\/li>\n<p><\/p>\n<li>For any non-null reference value <code>x<\/code>, <code>x.equals(null)<\/code> should return <code>false<\/code>.<\/li>\n<p>\n<\/ul>\n<\/blockquote>\n<p>\nIn fact, after studying a large body of Java code, the authors of a 2007 paper concluded that <strong>almost all implementations of equals methods are faulty<\/strong>.<a title=\"Vaziri, et al., \u201cDeclarative Object Identity Using Relation Types\u201c\" name=\"fn001t\" href=\"#fn001f\"><sup>1<\/sup><\/a>\n<\/p>\n<p>\nThere are quite a lot of HowTos available on the web. One of the best might be the article <a href=\"http:\/\/www.artima.com\/lejava\/articles\/equality.html\">&#8220;How to Write an Equality Method in Java&#8221;<\/a> by Martin Odersky, Lex Spoon, and Bill Venners.\n<\/p>\n<p>\nSo instead of repeating all the pitfalls you have to avoid, I&#8217;ll give you a <strong>sample implementation<\/strong><a name=\"fn002t\" href=\"#fn002f\"><sup>2<\/sup><\/a> of the <code>equals()<\/code>-method that follows the general contract using the example of an imaginary class <code>Point<\/code>:\n<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npublic boolean equals (final Object obj) {\r\n    if (this == obj) {\r\n      return true;\r\n    }\r\n    if (obj == null) {\r\n      return false;\r\n    }\r\n    if (this.getClass() != obj.getClass()) {\r\n      return false;\r\n    }\r\n    final Point other = (Point) obj;\r\n    if (this.x != other.x) {\r\n      return false;\r\n    }\r\n    if (this.y != other.y) {\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n<\/pre>\n<p>\n<strong>Be careful:<\/strong> Whenever you overwrite <code>equals()<\/code> it is generally necessary to override the <code>hashCode()<\/code>-method, too!\n<\/p>\n<p>\nIf you want to learn more about this topic, I suggest, you have a look at <a href=\"http:\/\/www.amazon.com\/gp\/product\/0321356683?ie=UTF8&#038;tag=devblog04-21&#038;linkCode=as2&#038;camp=1638&#038;creative=6742&#038;creativeASIN=0321356683\">Joshua Bloch&#8217;s <i>Effective Java Second Edition<\/i>. Addison-Wesley, 2008<\/a>.\n<\/p>\n<p><\/p>\n<p>\n<a name=\"fn001f\" href=\"#fn001t\">[1] <\/a>Vaziri, Mandana, Frank Tip, Stephen Fink, and Julian Dolby. \u201cDeclarative Object Identity Using Relation Types.\u201d In Proc. ECOOP 2007, pages 54\u201378. 2007.<br \/>\n<a name=\"fn002f\" href=\"#fn002t\">[2] <\/a><a href=\"http:\/\/www.artima.com\/forums\/flat.jsp?forum=226&#038;thread=259279&#038;start=30&#038;msRange=15\">http:\/\/www.artima.com\/forums\/flat.jsp?forum=226&#038;thread=259279&#038;start=30&#038;msRange=15<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>At first sight, implementing equals() doesn&#8217;t seem fairly hard. Unfortunately, it turns out that writing a correct equality method is surprisingly difficult: http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/lang\/Object.html The equals method implements an equivalence relation on non-null object references: It is reflexive: for any non-null reference value x, x.equals(x) should return true. It is symmetric: for any non-null reference values x and y, x.equals(y) should&#8230; <a href=\"https:\/\/possiblelossofprecision.net\/?p=823\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[4],"class_list":["post-823","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-java"],"_links":{"self":[{"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/posts\/823","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=823"}],"version-history":[{"count":31,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/posts\/823\/revisions"}],"predecessor-version":[{"id":863,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/posts\/823\/revisions\/863"}],"wp:attachment":[{"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=823"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=823"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=823"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}