{"id":411,"date":"2021-12-17T14:27:13","date_gmt":"2021-12-17T14:27:13","guid":{"rendered":"https:\/\/sidroniolima.com.br\/blog\/?p=411"},"modified":"2021-12-23T16:05:09","modified_gmt":"2021-12-23T16:05:09","slug":"effective-java-item-10-sobrescrever-o-metodo-equals-parte-1","status":"publish","type":"post","link":"https:\/\/sidroniolima.com.br\/blog\/2021\/12\/17\/effective-java-item-10-sobrescrever-o-metodo-equals-parte-1\/","title":{"rendered":"Effective Java &#8211; Item 10 &#8211; Sobrescrever o m\u00e9todo Equals (parte 1)"},"content":{"rendered":"\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?text=Sobrescrever%20o%20Object.equals%28Object%20obj%29%20obecendo%20%C3%A0%20especifica%C3%A7%C3%A3o&#038;hashtags=java%20equals%20effectivejava&#038;via=sidroniolima\" class=\"twitter-share-button\">Tweet<\/a><\/div>\n\n<p>Por vezes \u00e9 melhor herdar o m\u00e9todo <em>equals<\/em> da classe <em>Object<\/em> do que sobrescrev\u00ea-lo.<\/p>\n\n\n\n<p>Para que funcione de forma correta, o <em>equals<\/em> deve obedecer a um contrato geral, que define que ele seja:<\/p>\n\n\n\n<p>\u2022 Reflexivo: x != null => x.equals(x) == true;<br>\u2022 Sim\u00e9trico: x != null &amp; y != null => x.equals(y) == true &lt;=> y.equals(x) == true ;<br>\u2022 Transitivo: x != null &amp; y != null &amp; z != null => x.equals(y) == true &amp;  y.equals(z) == true &amp; x.equals(z) == true;<br>\u2022 Consistente: x != null &amp; y != null => x.equals(y) == true (|| false), quantas vezes for chamada.<br>\u2022 e quando nulo, x != null => x.equals(null) == false.<br><\/p>\n\n\n\n<p>O primeiro item diz que um objeto deve ser igual a ele mesmo. Num <em>Set<\/em>, por exemplo, se essa propriedade n\u00e3o estiver presente, um objeto pode ser inserido duas vezes ou n\u00e3o removido corretamente.<\/p>\n\n\n\n<p>Parece l\u00f3gico mas o desenvolvedor pode cair em armadilhas. Vejamos como n\u00e3o obedecer a segunda propriedade, que diz que dois objetos devem acordar sobre a forma com eles s\u00e3o iguais.<\/p>\n\n\n\n<p><code>\/\/ Broken - violates symmetry!<br>public final class CaseInsensitiveString {<br>private final String s;<br>public CaseInsensitiveString(String s) {<br>this.s = Objects.requireNonNull(s);<br>}<br>\/\/ Broken - violates symmetry!<br>@Override public boolean equals(Object o) {<br>if (o instanceof CaseInsensitiveString)<br>return s.equalsIgnoreCase(<br>((CaseInsensitiveString) o).s);<br>if (o instanceof String) \/\/ One-way interoperability!<br>return s.equalsIgnoreCase((String) o);<br>return false;<br>}<br>\u2026 \/\/ Remainder omitted<br>}<\/code><\/p>\n\n\n\n<p>Ao comparar essas duas strings, a segunda propriedade ser\u00e1 violada.<\/p>\n\n\n\n<p><code>CaseInsensitiveString cis = new CaseInsensitiveString(\"Polish\");<br>String s = \"polish\";<\/code><\/p>\n\n\n\n<p>Ao comparar <em>cis.equals(s) <\/em>ser\u00e1 retornado <em>true<\/em> j\u00e1 que ele foi constru\u00eddo para desconsiderar o &#8220;case&#8221;. O problema ocorre quando <em>s.equals(cis)<\/em>, que retorna <em>false<\/em>, j\u00e1 que n\u00e3o ignora o &#8220;case&#8221;. Um &#8220;claro caso de viola\u00e7\u00e3o da simetria&#8221;.<\/p>\n\n\n\n<p>Para corrigir, o m\u00e9todo <em>equals<\/em> deve ficar da seguinte forma.<\/p>\n\n\n\n<p><code>@Override public boolean equals(Object o) {<br>return o instanceof CaseInsensitiveString &amp;&amp;<br>((CaseInsensitiveString) o).s.equalsIgnoreCase(s);<br>}<\/code><\/p>\n\n\n\n<p>Esque\u00e7a a tentativa de lidar com <em>String<\/em>, o que \u00e9 chamado no livro de &#8220;<code>One-way interoperability!<\/code>&#8220;.<\/p>\n\n\n\n<p>Nesse post falei da primeira e segunda propriedade, sem as quais podem ocorrer inconsist\u00eancias e causar exce\u00e7\u00f5es.<\/p>\n\n\n\n<p>Ent\u00e3o at\u00e9 o pr\u00f3ximo, no qual continuarei com as outras propriedades.<\/p>\n\n\n\n<p>PS.: a especifica\u00e7\u00e3o do m\u00e9todo <em>equals<\/em> \u00e9 encontrada em <a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/lang\/Object.html#equals(java.lang.Object)\" data-type=\"URL\" data-id=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/lang\/Object.html#equals(java.lang.Object)\">https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/lang\/Object.html#equals(java.lang.Object)<\/a>.<\/p>\n\n\n\n<p>PS.2: nada \u00e9 trivial.<\/p>\n\n\n\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?text=Sobrescrever%20o%20Object.equals%28Object%20obj%29%20obecendo%20%C3%A0%20especifica%C3%A7%C3%A3o&#038;hashtags=java%20equals%20effectivejava&#038;via=sidroniolima\" class=\"twitter-share-button\">Tweet<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Por vezes \u00e9 melhor herdar o m\u00e9todo equals da classe Object do que sobrescrev\u00ea-lo. Para que funcione de forma correta, o equals deve obedecer a um contrato geral, que define que ele seja: \u2022 Reflexivo: x != null => x.equals(x) == true;\u2022 Sim\u00e9trico: x != null &amp; y != null => x.equals(y) == true &lt;=> [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[27,116],"tags":[115,29],"class_list":["post-411","post","type-post","status-publish","format-standard","hentry","category-java","category-performance","tag-effective-java","tag-java"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/411","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/comments?post=411"}],"version-history":[{"count":2,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/411\/revisions"}],"predecessor-version":[{"id":413,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/411\/revisions\/413"}],"wp:attachment":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/media?parent=411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/categories?post=411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/tags?post=411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}