Java の *任意の* クラスのすべてのインスタンスに完全な順序付けを課す
質問
次のコードが Comparator の Javadoc で指定されているすべての条件を保証するかどうかはわかりません。
class TotalOrder<T> implements Comparator<T> {
public boolean compare(T o1, T o2) {
if (o1 == o2 || equal(o1, o2)) return 0;
int h1 = System.identityHashCode(o1);
int h2 = System.identityHashCode(o2);
if (h1 != h2) {
return h1 < h2 ? -1 : 1;
}
// equals returned false but identity hash code was same, assume o1 == o2
return 0;
}
boolean equal(Object o1, Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
}
}
上記のコードは、クラスが Comparable を実装していない場合でも、クラスのすべてのインスタンスに完全な順序付けを適用しますか?
解決
ねえ、私が見つけたものを見てください!
http://gafter.blogspot.com/2007/03/compact-object-comparator.html
そうそう、IdentityHashMap (Java 6 以降のみ) のことを忘れていました。コンパレータを解放するときに注意する必要があります。
他のヒント
ねえ、私が見つけたものを見てください!
http://gafter.blogspot.com/2007/03/compact-object-comparator.html
これこそまさに私が探していたものです。
あなたはコメントで次のように答えました。
等しい場合は false が返されましたが、アイデンティティ ハッシュ コードは同じでした。o1 == o2 と仮定します。
残念ながら、それを想定することはできません。ほとんどの場合、これでうまくいきますが、例外的にうまくいかない場合もあります。そしてそれがいつ起こるかはわかりません。このようなケースが発生すると、たとえば TreeSet 内のインスタンスが失われる可能性があります。
この条項が満たされていないため、そうではないと思います。
最後に、実装者は、x.compareTo(y)==0 がすべての z に対して sgn(x.compareTo(z)) == sgn(y.compareTo(z)) を意味することを確認する必要があります。
equal(o1, o2) は o1 の equals の実装に依存しているため、論理的に等しい (equals によって決定される) 2 つのオブジェクトであっても、2 つの異なるidentityHashCode を持ちます。
したがって、それらを 3 番目のオブジェクト (z) と比較すると、compareTo に異なる値が生成される可能性があります。
意味をなす?
最後に到達した場合は、おそらく例外を発生させる必要があります return 0
line -- ハッシュの衝突が発生したとき。質問がありますが、ハッシュの全体的な順序付けを行っていますが、それは問題ないと思いますが、辞書編集上の順序を定義するために何らかの関数を渡す必要はありませんか?
int h1 = System.identityHashCode(o1);
int h2 = System.identityHashCode(o2);
if (h1 != h2) {
return h1 < h2 ? -1 : 1;
}
実数を形成する 2 つの整数のタプルとしてオブジェクトがあると想像できます。ただし、オブジェクトのハッシュを取得しているだけなので、適切な順序は得られません。ハッシュ化があなたの意図するところであるかどうかは、すべてあなた次第ですが、私にとって、それはあまり意味がありません。
私はこれが理想的ではないことに同意するため、コメントしました。助言がありますか?
2 つのインスタンスを区別できる唯一のものにアクセスできないため、これを解決する方法があると思います。メモリ内のアドレス。そこで、私からの提案は 1 つだけです。Java で一般的な注文プロセスを行う必要性を再考してください:-)
についてはよくわかりませんが、 System.identityHashCode(Object)
. 。それはかなりのことです == に使用されます。むしろ、 Object.hashCode()
- それはより並行しています Object.equals(Object)
.