Your SlideShare is downloading. ×
0
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
こんなEqualsは嫌だ
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

こんなEqualsは嫌だ

1,044

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,044
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. こんな equals/hashCodeは嫌だ<br />大阪EffectiveJava読書会 第2回<br />2011/06/18 お だ<br />
  • 2. 自己紹介<br /><ul><li>織田 信亮(おだ しんすけ)
  • 3. 大阪で 開発者 してます。
  • 4. MS 系の情報を追っかけてます
  • 5. Id:odashinsuke@shinsukeoda
  • 6. SQL World (SQL Server のコミュニティ)
  • 7. 日本Grails/Groovyユーザグループ</li></li></ul><li><ul><li>第3章 項目8 equals を… P.33
  • 8. 反射的</li></ul>x.equals(x)<br /><ul><li>対称的</li></ul>y.equals(x) ⇒x.equals(y)<br /><ul><li>推移的</li></ul>x.equals(y) && y.equals(z) ⇒x.equals(z)<br /><ul><li>整合的</li></ul>x.equals(y) ⇒x.equals(y)<br />
  • 9. <ul><li>文字に置き換えると…
  • 10. 反射的</li></ul>A = A<br /><ul><li>対称的</li></ul>A = B ⇒ B = A<br /><ul><li>推移的</li></ul>A = B & B = C ⇒ A = C<br /><ul><li>整合的</li></ul>上手く表せない orz...<br />
  • 11. 反射的 でない!<br />final class反射的{<br />publicint id;<br /> @Override<br />publicboolean equals(Object obj) {<br />if (!(objinstanceof反射的)) { returnfalse; }<br />returnthis.id == ((反射的)obj).id + 1;<br />}<br />}<br />反射的 x = new反射的();<br />x.id = 1;<br />System.out.println("x.equals(x):" + x.equals(x)); // false<br />
  • 12. 対称的 でない!<br />final class対称的{<br />publicint value;<br /> @Override<br />publicboolean equals(Object obj) {<br />if (this == obj) { returntrue; }<br />if (obj == null) { returnfalse; }<br />try {<br /> Field f = obj.getClass().getDeclaredField("value");<br />f.setAccessible(true);<br /> Object objId = f.get(obj);<br />returnthis.value == (Integer)objId; <br /> } catch (Throwable e) { // ガン無視!<br />returnfalse;<br />}<br />}<br />}<br />
  • 13. 対称的 でない!<br />対称的 x = new対称的();<br />x.value= 1;<br />Integer y = Integer.valueOf(1);<br />System.out.println("x.equals(y):" + x.equals(y)); // true<br />System.out.println("y.equals(x):" + y.equals(x)); // false<br />
  • 14. 推移的 でない!<br />classSuper推移的{<br />publicint id;<br /> @Override<br />publicboolean equals(Object obj) {<br />if (this == obj) { returntrue; }<br />if (!(objinstanceofSuper推移的)) { returnfalse; }<br />returnthis.id == ((Super推移的)obj).id;<br />}<br />}<br />final classSub推移的 extends Super推移的{<br />publicintseq;<br /> @Override<br />publicboolean equals(Object obj) {<br />if (this == obj) { returntrue; }<br />if (!(objinstanceofSuper推移的)) { returnfalse; }<br />if (objinstanceofSub推移的) {<br />returnthis.id == ((Sub推移的)obj).id && <br />this.seq == ((Sub推移的)obj).seq;<br />}<br />returnsuper.equals(obj);<br />}<br />}<br />
  • 15. 推移的 でない!<br />Sub推移的 x = new Sub推移的();<br />x.id = 1;<br />x.seq= 1;<br />Super推移的 y = new Super推移的();<br />y.id = 1;<br />Sub推移的 z = new Sub推移的();<br />z.id = 1;<br />z.seq= 2;<br />System.out.println(“x.equals(y):”+ x.equals(y));// true<br />System.out.println("y.equals(z):" + y.equals(z)); // true<br />System.out.println("x.equals(z):" + x.equals(z)); // false<br />
  • 16. 整合的でない!<br />final class整合的{<br />publicint id;<br /> @Override<br />publicboolean equals(Object obj) {<br />if (this == obj) { returntrue; }<br />if (!(objinstanceof整合的)) { returnfalse; }<br />returnthis.id++ == ((整合的)obj).id;<br />}<br />}<br />整合的 x = new整合的();<br />x.id = 1;<br />整合的 y = new整合的();<br />y.id = 1;<br />System.out.println("x.equals(y):" + x.equals(y)); // true<br />System.out.println("x.equals(y):" + x.equals(y)); // false<br />
  • 17. 例外を吐く<br />final class例外{<br />publicint id;<br /> @Override<br />publicboolean equals(Object obj) {<br />returnthis.id == ((例外)obj).id;<br />}<br />}<br />例外 x= new例外();<br />x.id = 1;<br />try{<br />System.out.println(x.equals(null));<br />} catch (Throwable e) {<br />System.out.println(“equals で例外とかありえなーい”); // こっち通る<br />}<br />
  • 18. まとも<br />final classまとも{<br />publicint id;<br /> @Override<br />publicboolean equals(Object obj) {<br />if (this == obj) { returntrue; }<br />if (!(objinstanceofまとも)) { returnfalse; }<br />returnthis.id == ((まとも)obj).id;<br />}<br /> @Override<br />publicinthashCode() { returnthis.id; }<br />}<br />
  • 19. まとも<br />まとも x= new まとも();<br />x.id = 1;<br />まとも y = new まとも();<br />y.id = 1;<br />まとも z = new まとも();<br />z.id = 1;<br />System.out.println("x.equals(x):" + x.equals(x)); // true<br />System.out.println("x.equals(y):" + x.equals(y)); // true<br />System.out.println("y.equals(x):" + y.equals(x)); // true<br />System.out.println("x.equals(y):" + x.equals(y)); // true<br />System.out.println("y.equals(z):" + y.equals(z)); // true<br />System.out.println("x.equals(z):" + x.equals(z)); // true<br />System.out.println("x.equals(y):" + x.equals(y)); // true<br />System.out.println("x.equals(y):" + x.equals(y)); // true<br />
  • 20. <ul><li>第3章 項目9 equals を… 常に hashCodeを… P.45
  • 21. Object の状態が変わらないなら、hashCodeは常に同じ値を返す
  • 22. equals での比較結果が true なら、hashCodeを比較しても同じになる
  • 23. equals での比較結果が falseでも、hashCodeが同じになっても良い</li></li></ul><li>まとも<br />final classまとも{<br />publicint id;<br /> @Override<br />publicboolean equals(Object obj) {<br />if (this == obj) { returntrue; }<br />if (!(objinstanceofまとも)) { returnfalse; }<br />returnthis.id == ((まとも)obj).id;<br />}<br /> @Override<br />publicinthashCode() { returnthis.id; }<br />}<br />
  • 24. 正しいですね!<br />
  • 25. <ul><li>項目10 GetHashCode() の罠に注意する P.56</li></ul>こんな内容のことが書いています<br /><ul><li>ハッシュコンテナのキーとして使用されることになる値型を作成する場合、その型は不変型にすべき。</li></li></ul><li>??<br />
  • 26. http://www.amazon.co.jp/Effective-C-%E3%83%93%E3%83%AB-%E3%83%AF%E3%82%B0%E3%83%8A%E3%83%BC/dp/4798119539<br />
  • 27. HashMapで利用すると…<br />まとも x= new まとも();<br />x.id = 1;<br />HashMap<まとも, String> map = <br />newHashMap<まとも, String>();<br />map.put(x, "A");<br />System.out.println(map.get(x)); // A<br />x.id = 3;<br />System.out.println(map.get(x)); // null<br />
  • 28. まとめ<br />
  • 29. <ul><li>Hash の KEY として利用するなら、少なくとも hashCodeに利用するフィールドは、Immutable(不変)が良さそう。
  • 30. って、中々 Hash の KEY には使わないよね…。</li>

×