Float,Doubleのequalsとfloat,doubleの==
EffectiveJava(2版)のItem8に、equals実装時float(double)は他のプリミティブが==で比較してるのと異なり
Float.compareで比較してねと書いてあったので理由を調べてみる。
Float.NaNと-0.0fが理由らしいが、詳しくはFloat.equalsのドキュメント見ぃやとあったので見てみると、
・f1 および f2 の両方が Float.NaN を表す場合は、Float.NaN==Float.NaN の値が false であっても、equals メソッドは true を返す
・f1 が +0.0f を表し、f2 が -0.0f を表す場合、あるいは f1 が -0.0f を表し、f2 が +0.0f を表す場合は、0.0f==-0.0f の値が true であっても、equal メソッドの結果は false になる
この定義によって、ハッシュテーブルは正しく動作します。
Float.equals
一応確認。
Float f1 = Float.NaN; Float f2 = Float.NaN; Float f3 = 0.0f; Float f4 = -0.0f; System.out.println("f1.floatValue() : " + f1.floatValue()); System.out.println("f2.floatValue() : " + f2.floatValue()); System.out.println("f3.floatValue() : " + f3.floatValue()); System.out.println("f4.floatValue() : " + f4.floatValue()); System.out.println("f1.floatValue() == f2.floatValue(): " + (f1.floatValue() == f2.floatValue())); System.out.println("f1.equals(f2) : " + f1.equals(f2)); System.out.println("f3.floatValue() == f4.floatValue(): " + (f3.floatValue() == f4.floatValue())); System.out.println("f3.equals(f4) : " + f3.equals(f4)); System.out.println("Float.compare(f1, f2) : " + Float.compare(f1, f2)); System.out.println("Float.compare(f3, f4) : " + Float.compare(f3, f4));
実行結果
f1.floatValue() : NaN f2.floatValue() : NaN f3.floatValue() : 0.0 f4.floatValue() : -0.0 f1.floatValue() == f2.floatValue(): false f1.equals(f2) : true f3.floatValue() == f4.floatValue(): true f3.equals(f4) : false Float.compare(f1, f2) : 0 Float.compare(f3, f4) : 1
(Doubleでもまったく同じ結果)
確かにfloatの==とFloat.equalsで挙動が違う。
で、これはハッシュのキーに使う為だと。
Float.compareはFloat.equalsの結果と同じなのでこれを使ってねということか。
理由はわかったけど、そもそも何でfloatの==はFloat.equalsと挙動が異なるのかね?
同じような疑問持った人見っけた
http://d.hatena.ne.jp/Kappuccino/20080805/1217905115
http://www.coderanch.com/t/269299/Programmer-Certification-SCJP/certification/NAN