読者です 読者をやめる 読者になる 読者になる

Effective Javaを読んでいる⑫

Java

Comparebleの話

Comparable (Java Platform SE 7)

おやくそく

  1. sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
    そして、x.compareTo(y)が例外を投げるなら、y.compareTo(x)も投げること。
  2. 関係が連続していること。 x.compareTo(y) > 0 && y.compareTo(z) > 0 なら、x.compareTo(z) > 0
    x > y で y > z なら x > y > zであること。
  3. x.compareTo(y) == 0 なら sgn(x.compareTo(z)) == sgn(y.compareTo(z)) であること。
    xとyが同じならxとz、yとzの比較結果が等しくなること。
  4. (x.compareTo(y) == 0) == (x.equals(y)) ※厳密に必要とはされないが、違反する場合はそれを記載すべき。

sgnってなんすか
符号関数 - Wikipedia
-1,0,1のいずれかを返却する関数

equalsとcompareToの結果が矛盾する場合・・・

"等しいこと"を判断する基準がequalsの場合とcompareToの場合で結果が変わってしまう。例えば、

  1. BigDecimalはequalsではスケールを意識するがcompareToでは意識しない。
  2. HashSetは同一性の判断にequalsを使う。TreeSetではcompareToを使う。
    のような状況で、new BigDecimal("1.0")とnew BigDecimal("1.00")をHashSetに加えると要素は2つになるが、TreeSetでは1つになる。

BigDecimal (Java Platform SE 6)

例えばintの比較だったら
if( args.age > this.age) { return 1} else { return -1}でもいいけど
return args.age - this.age でもいい。(比較の基準がage以外の場合は差が0でないことを確認すること。) でも結果的に
args.age - this.ageの値がintの範囲をオーバーするとカオスになるので気をつけること。
殆どの場合はうまく動く分デバッグがしづらいぞ!