3

次のコードが 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 を実装していない場合でも、クラスのすべてのインスタンスに完全な順序付けを課しますか?

4

7 に答える 7

2

ねえ、私が見つけたものを見てください!

http://gafter.blogspot.com/2007/03/compact-object-comparator.html

これはまさに私が探していたものです。

于 2008-08-26T16:03:27.633 に答える
2

ねえ、私が見つけたものを見てください!

http://gafter.blogspot.com/2007/03/compact-object-comparator.html

そうそう、IdentityHashMap を忘れていました (Java 6 以降のみ)。コンパレータをリリースする際に注意を払う必要があります。

于 2008-08-26T16:08:54.250 に答える
1

あなたはあなたのコメントで答えました:

等しいがfalseを返しましたが、IDハッシュコードは同じでした。o1==o2と仮定します。

残念ながら、それを想定することはできません。ほとんどの場合は機能しますが、一部の例外的なケースでは機能しません。そして、あなたはいつを知ることができません。このようなケースが発生すると、たとえばTreeSetsのインスタンスが失われる可能性があります。

于 2008-08-26T15:20:55.053 に答える
1

この条項が満たされていないので、私はそうは思わない:

最後に、実装者は、すべてのzについて、x.compareTo(y)== 0がsgn(x.compareTo(z))== sgn(y.compareTo(z))を意味することを確認する必要があります。

equal(o1、o2)はo1のequalsの実装に依存するため、論理的に等しい2つのオブジェクト(equalsによって決定される)には、2つの異なるidentityHashCodesがあります。

したがって、それらを3番目のオブジェクト(z)と比較すると、compareToに対して異なる値が生成される可能性があります。

わかる?

于 2008-08-26T15:32:28.317 に答える
1

最後の行に到達した場合は、おそらく例外を発生させる必要があります --return 0ハッシュの衝突が発生した場合。ただし、質問があります。あなたはハッシュの完全な順序付けを行っていますが、これは問題ないと思いますが、辞書式順序を定義するために関数を渡す必要はありませんか?

    int h1 = System.identityHashCode(o1);
    int h2 = System.identityHashCode(o2);
    if (h1 != h2) {
        return h1 < h2 ? -1 : 1;
    }

実数を形成する 2 つの整数のタプルとしてオブジェクトを持っていると想像できます。ただし、オブジェクトのハッシュのみを取得しているため、適切な順序は得られません。ハッシュ化が意図したものである場合、これはすべてあなた次第ですが、私にとってはあまり意味がありません。

于 2008-08-26T15:44:56.633 に答える
0

これは理想的ではないことに同意するので、コメントします。助言がありますか?

2つのインスタンスを区別できる唯一のもの、つまりメモリ内のアドレスにアクセスできないため、これを解決できる方法があると思います。したがって、私は1つの提案しかありません.Javaで一般的な全注文プロセスを行う必要があることを再考してください:-)

于 2008-08-26T15:51:19.550 に答える
0

についてはよくわかりませんSystem.identityHashCode(Object)。これが==の用途です。むしろ を使用したいかもしれませんObject.hashCode()- それは とより並行していObject.equals(Object)ます。

于 2008-08-26T15:35:07.047 に答える