SlideShare a Scribd company logo
1 of 22
こんな equals/hashCodeは嫌だ 大阪EffectiveJava読書会 第2回 2011/06/18 お だ
自己紹介 ,[object Object]
大阪で 開発者 してます。
MS 系の情報を追っかけてます
Id:odashinsuke@shinsukeoda
SQL World (SQL Server のコミュニティ)
日本Grails/Groovyユーザグループ,[object Object]
反射的x.equals(x) ,[object Object],y.equals(x) ⇒x.equals(y) ,[object Object],x.equals(y) && y.equals(z) ⇒x.equals(z) ,[object Object],x.equals(y) ⇒x.equals(y)
[object Object]
反射的A = A ,[object Object],A = B ⇒ B = A ,[object Object],A = B & B = C ⇒ A = C ,[object Object],上手く表せない orz...
反射的 でない! final class反射的{ publicint id;   @Override publicboolean equals(Object obj) { if (!(objinstanceof反射的)) { returnfalse; } returnthis.id == ((反射的)obj).id + 1; } } 反射的 x = new反射的(); x.id = 1; System.out.println("x.equals(x):" + x.equals(x)); // false
対称的 でない! final class対称的{ publicint value;   @Override publicboolean equals(Object obj) { if (this == obj) { returntrue; } if (obj == null) { returnfalse; } try {       Field f = obj.getClass().getDeclaredField("value"); f.setAccessible(true);       Object objId = f.get(obj); returnthis.value == (Integer)objId;      } catch (Throwable e) { // ガン無視! returnfalse; } } }
対称的 でない! 対称的 x = new対称的(); x.value= 1; Integer y = Integer.valueOf(1); System.out.println("x.equals(y):" + x.equals(y)); // true System.out.println("y.equals(x):" + y.equals(x)); // false
推移的 でない! classSuper推移的{ publicint id;   @Override publicboolean equals(Object obj) { if (this == obj) { returntrue; } if (!(objinstanceofSuper推移的)) { returnfalse; } returnthis.id == ((Super推移的)obj).id; } } final classSub推移的 extends Super推移的{ publicintseq;   @Override publicboolean equals(Object obj) { if (this == obj) { returntrue; } if (!(objinstanceofSuper推移的)) { returnfalse; } if (objinstanceofSub推移的) { returnthis.id == ((Sub推移的)obj).id &&  this.seq == ((Sub推移的)obj).seq; } returnsuper.equals(obj); } }
推移的 でない! Sub推移的 x = new Sub推移的(); x.id = 1; x.seq= 1; Super推移的 y = new Super推移的(); y.id = 1; Sub推移的 z = new Sub推移的(); z.id = 1; z.seq= 2; System.out.println(“x.equals(y):”+ x.equals(y));// true System.out.println("y.equals(z):" + y.equals(z)); // true System.out.println("x.equals(z):" + x.equals(z)); // false
整合的でない! final class整合的{ publicint id;   @Override publicboolean equals(Object obj) { if (this == obj) { returntrue; } if (!(objinstanceof整合的)) { returnfalse; } returnthis.id++ == ((整合的)obj).id; } } 整合的 x = new整合的(); x.id = 1; 整合的 y = new整合的(); y.id = 1; System.out.println("x.equals(y):" + x.equals(y)); // true System.out.println("x.equals(y):" + x.equals(y)); // false
例外を吐く final class例外{ publicint id;   @Override publicboolean equals(Object obj) { returnthis.id == ((例外)obj).id; } } 例外 x= new例外(); x.id = 1; try{ System.out.println(x.equals(null)); } catch (Throwable e) { System.out.println(“equals で例外とかありえなーい”); // こっち通る }
まとも final classまとも{ publicint id;   @Override publicboolean equals(Object obj) { if (this == obj) { returntrue; } if (!(objinstanceofまとも)) { returnfalse; } returnthis.id == ((まとも)obj).id; }   @Override publicinthashCode() { returnthis.id; } }
まとも まとも x= new まとも(); x.id = 1; まとも y = new まとも(); y.id = 1; まとも z = new まとも(); z.id = 1; System.out.println("x.equals(x):" + x.equals(x)); // true System.out.println("x.equals(y):" + x.equals(y)); // true System.out.println("y.equals(x):" + y.equals(x)); // true System.out.println("x.equals(y):" + x.equals(y)); // true System.out.println("y.equals(z):" + y.equals(z)); // true System.out.println("x.equals(z):" + x.equals(z)); // true System.out.println("x.equals(y):" + x.equals(y)); // true System.out.println("x.equals(y):" + x.equals(y)); // true
[object Object]
Object の状態が変わらないなら、hashCodeは常に同じ値を返す
equals での比較結果が true なら、hashCodeを比較しても同じになる

More Related Content

What's hot

Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]
Ra Zon
 

What's hot (12)

関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]
 
Linqことはじめ
LinqことはじめLinqことはじめ
Linqことはじめ
 
Swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorp
Swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorpSwift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorp
Swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorp
 
関数型プログラミング in javascript
関数型プログラミング in javascript関数型プログラミング in javascript
関数型プログラミング in javascript
 
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数
 
(Lambdaだけで) 純LISPのような ナニかを作る
(Lambdaだけで)純LISPのようなナニかを作る(Lambdaだけで)純LISPのようなナニかを作る
(Lambdaだけで) 純LISPのような ナニかを作る
 
Sized Linear Algebra Package のチュートリアル
Sized Linear Algebra Package のチュートリアルSized Linear Algebra Package のチュートリアル
Sized Linear Algebra Package のチュートリアル
 
Swift らしい表現を目指そう #eventdots
Swift らしい表現を目指そう #eventdotsSwift らしい表現を目指そう #eventdots
Swift らしい表現を目指そう #eventdots
 
すごいHaskell読書会
すごいHaskell読書会すごいHaskell読書会
すごいHaskell読書会
 
(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する
 

Viewers also liked (10)

Selenium webdriver使ってみようず
Selenium webdriver使ってみようずSelenium webdriver使ってみようず
Selenium webdriver使ってみようず
 
The security monitoring and attack detection planning guide
The security monitoring and attack detection planning guideThe security monitoring and attack detection planning guide
The security monitoring and attack detection planning guide
 
Hentai advent calendar 2012 番外編
Hentai advent calendar 2012 番外編Hentai advent calendar 2012 番外編
Hentai advent calendar 2012 番外編
 
本当にあった怖い話し (やきに駆動 2.0)
本当にあった怖い話し (やきに駆動 2.0)本当にあった怖い話し (やきに駆動 2.0)
本当にあった怖い話し (やきに駆動 2.0)
 
BeanValidation
BeanValidationBeanValidation
BeanValidation
 
Sql world とは
Sql world とはSql world とは
Sql world とは
 
Ms build 色々出来るよ
Ms build 色々出来るよMs build 色々出来るよ
Ms build 色々出来るよ
 
データを追っかけよう!
データを追っかけよう!データを追っかけよう!
データを追っかけよう!
 
Management studio の便利機能の紹介
Management studio の便利機能の紹介Management studio の便利機能の紹介
Management studio の便利機能の紹介
 
Selenium 触ってみよう
Selenium 触ってみようSelenium 触ってみよう
Selenium 触ってみよう
 

Similar to こんなEqualsは嫌だ

虚数は作れる!Swift で学ぶ複素数
虚数は作れる!Swift で学ぶ複素数虚数は作れる!Swift で学ぶ複素数
虚数は作れる!Swift で学ぶ複素数
Taketo Sano
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
Akira Inoue
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
今さら始めるCoffeeScript
今さら始めるCoffeeScript今さら始めるCoffeeScript
今さら始めるCoffeeScript
Ashitaba YOSHIOKA
 

Similar to こんなEqualsは嫌だ (20)

Haskell勉強会2 in ie
Haskell勉強会2 in ieHaskell勉強会2 in ie
Haskell勉強会2 in ie
 
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScript
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
虚数は作れる!Swift で学ぶ複素数
虚数は作れる!Swift で学ぶ複素数虚数は作れる!Swift で学ぶ複素数
虚数は作れる!Swift で学ぶ複素数
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座
 
Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)
 
Lispでやる記号微分
Lispでやる記号微分Lispでやる記号微分
Lispでやる記号微分
 
Haskell
HaskellHaskell
Haskell
 
今さら始めるCoffeeScript
今さら始めるCoffeeScript今さら始めるCoffeeScript
今さら始めるCoffeeScript
 
大人のお型付け
大人のお型付け大人のお型付け
大人のお型付け
 
Material
MaterialMaterial
Material
 
Implicit Explicit Scala
Implicit Explicit ScalaImplicit Explicit Scala
Implicit Explicit Scala
 
Testman
TestmanTestman
Testman
 
 
  
 
 
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesasm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
 
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
 

More from Oda Shinsuke

More from Oda Shinsuke (20)

SQL Server2022_PSPoptimization_pub.pdf
SQL Server2022_PSPoptimization_pub.pdfSQL Server2022_PSPoptimization_pub.pdf
SQL Server2022_PSPoptimization_pub.pdf
 
What's hyperscale
What's hyperscaleWhat's hyperscale
What's hyperscale
 
Dot net+sql server tips
Dot net+sql server tipsDot net+sql server tips
Dot net+sql server tips
 
Sql server 2019 ざっくり紹介
Sql server 2019  ざっくり紹介Sql server 2019  ざっくり紹介
Sql server 2019 ざっくり紹介
 
Spark on sql server?
Spark on sql server?Spark on sql server?
Spark on sql server?
 
SQL Server のロック概要
SQL Server のロック概要SQL Server のロック概要
SQL Server のロック概要
 
Blazor 触ってみた
Blazor 触ってみたBlazor 触ってみた
Blazor 触ってみた
 
Linux + PHP でも SQL Server
Linux + PHP でも SQL ServerLinux + PHP でも SQL Server
Linux + PHP でも SQL Server
 
グラフデータベースの話し
グラフデータベースの話しグラフデータベースの話し
グラフデータベースの話し
 
Sql server 2017 新機能のご紹介
Sql server 2017 新機能のご紹介Sql server 2017 新機能のご紹介
Sql server 2017 新機能のご紹介
 
Sql server 2017 からはじめる graph データベース
Sql server 2017 からはじめる graph データベースSql server 2017 からはじめる graph データベース
Sql server 2017 からはじめる graph データベース
 
Transaction scopeまだダメ
Transaction scopeまだダメTransaction scopeまだダメ
Transaction scopeまだダメ
 
Sql serverと他dbの違いを押さえよう!
Sql serverと他dbの違いを押さえよう!Sql serverと他dbの違いを押さえよう!
Sql serverと他dbの違いを押さえよう!
 
2016年を振り返って
2016年を振り返って2016年を振り返って
2016年を振り返って
 
Sql world とは
Sql world とはSql world とは
Sql world とは
 
開発者の方向けの Sql server(db) t sql 振り返り
開発者の方向けの Sql server(db) t sql 振り返り開発者の方向けの Sql server(db) t sql 振り返り
開発者の方向けの Sql server(db) t sql 振り返り
 
Ms build 触ってみよう
Ms build 触ってみようMs build 触ってみよう
Ms build 触ってみよう
 
Sql server2014復習とsqlserver2016の紹介
Sql server2014復習とsqlserver2016の紹介Sql server2014復習とsqlserver2016の紹介
Sql server2014復習とsqlserver2016の紹介
 
Sql server sql database 最新機能紹介
Sql server sql database 最新機能紹介Sql server sql database 最新機能紹介
Sql server sql database 最新機能紹介
 
Sql database のご紹介
Sql database のご紹介Sql database のご紹介
Sql database のご紹介
 

こんなEqualsは嫌だ

  • 2.
  • 6. SQL World (SQL Server のコミュニティ)
  • 7.
  • 8.
  • 9.
  • 10.
  • 11. 反射的 でない! final class反射的{ publicint id; @Override publicboolean equals(Object obj) { if (!(objinstanceof反射的)) { returnfalse; } returnthis.id == ((反射的)obj).id + 1; } } 反射的 x = new反射的(); x.id = 1; System.out.println("x.equals(x):" + x.equals(x)); // false
  • 12. 対称的 でない! final class対称的{ publicint value; @Override publicboolean equals(Object obj) { if (this == obj) { returntrue; } if (obj == null) { returnfalse; } try { Field f = obj.getClass().getDeclaredField("value"); f.setAccessible(true); Object objId = f.get(obj); returnthis.value == (Integer)objId; } catch (Throwable e) { // ガン無視! returnfalse; } } }
  • 13. 対称的 でない! 対称的 x = new対称的(); x.value= 1; Integer y = Integer.valueOf(1); System.out.println("x.equals(y):" + x.equals(y)); // true System.out.println("y.equals(x):" + y.equals(x)); // false
  • 14. 推移的 でない! classSuper推移的{ publicint id; @Override publicboolean equals(Object obj) { if (this == obj) { returntrue; } if (!(objinstanceofSuper推移的)) { returnfalse; } returnthis.id == ((Super推移的)obj).id; } } final classSub推移的 extends Super推移的{ publicintseq; @Override publicboolean equals(Object obj) { if (this == obj) { returntrue; } if (!(objinstanceofSuper推移的)) { returnfalse; } if (objinstanceofSub推移的) { returnthis.id == ((Sub推移的)obj).id && this.seq == ((Sub推移的)obj).seq; } returnsuper.equals(obj); } }
  • 15. 推移的 でない! Sub推移的 x = new Sub推移的(); x.id = 1; x.seq= 1; Super推移的 y = new Super推移的(); y.id = 1; Sub推移的 z = new Sub推移的(); z.id = 1; z.seq= 2; System.out.println(“x.equals(y):”+ x.equals(y));// true System.out.println("y.equals(z):" + y.equals(z)); // true System.out.println("x.equals(z):" + x.equals(z)); // false
  • 16. 整合的でない! final class整合的{ publicint id; @Override publicboolean equals(Object obj) { if (this == obj) { returntrue; } if (!(objinstanceof整合的)) { returnfalse; } returnthis.id++ == ((整合的)obj).id; } } 整合的 x = new整合的(); x.id = 1; 整合的 y = new整合的(); y.id = 1; System.out.println("x.equals(y):" + x.equals(y)); // true System.out.println("x.equals(y):" + x.equals(y)); // false
  • 17. 例外を吐く final class例外{ publicint id; @Override publicboolean equals(Object obj) { returnthis.id == ((例外)obj).id; } } 例外 x= new例外(); x.id = 1; try{ System.out.println(x.equals(null)); } catch (Throwable e) { System.out.println(“equals で例外とかありえなーい”); // こっち通る }
  • 18. まとも final classまとも{ publicint id; @Override publicboolean equals(Object obj) { if (this == obj) { returntrue; } if (!(objinstanceofまとも)) { returnfalse; } returnthis.id == ((まとも)obj).id; } @Override publicinthashCode() { returnthis.id; } }
  • 19. まとも まとも x= new まとも(); x.id = 1; まとも y = new まとも(); y.id = 1; まとも z = new まとも(); z.id = 1; System.out.println("x.equals(x):" + x.equals(x)); // true System.out.println("x.equals(y):" + x.equals(y)); // true System.out.println("y.equals(x):" + y.equals(x)); // true System.out.println("x.equals(y):" + x.equals(y)); // true System.out.println("y.equals(z):" + y.equals(z)); // true System.out.println("x.equals(z):" + x.equals(z)); // true System.out.println("x.equals(y):" + x.equals(y)); // true System.out.println("x.equals(y):" + x.equals(y)); // true
  • 20.
  • 22. equals での比較結果が true なら、hashCodeを比較しても同じになる
  • 23.
  • 25.
  • 27. HashMapで利用すると… まとも x= new まとも(); x.id = 1; HashMap<まとも, String> map = newHashMap<まとも, String>(); map.put(x, "A"); System.out.println(map.get(x)); // A x.id = 3; System.out.println(map.get(x)); // null
  • 29.
  • 30. って、中々 Hash の KEY には使わないよね…。