1

私が次のことをすると

myObject.myMethod(myClass.getComparator());

public void myMethod(Comparator<? super myOtherObject> comparator) {
if (comparator.equals(myClass.getComparator()) {
 //do sth
}
}

とmyClassで

   static Comparator<ListItem> getComparator() {
        return new Comparator<myOtherObject>() {
            public int compare(myOtherObjectitem1, myOtherObjectitem2) {
                return (Integer.valueOf(myOtherObject.getRating()).compareTo(Integer.valueOf(myOtherObject.getRating())));
            }
        };
    }

その場合、「//dosth」は実行されません。したがって、getComparatorから2回取得するオブジェクトは異なります。どうしてそれができるのでしょうか?どのコンパレータ「myMethod」が取得するかを確認する機会はありますか?

4

2 に答える 2

3

equals次の行でメソッドを呼び出しています。

if (comparator.equals(myClass.getComparator())

Comparatorクラス(匿名の内部クラス)でこのメソッドを明示的に定義していないため、これはデフォルトで継承されたバージョンになりObjectます。これは、2つの参照がまったく同じオブジェクトである場合にのみ等しいと見なします。

そして、getComparator()メソッドはreturn new Comparator() { ... }を示しているので、コンストラクターを呼び出し、呼び出されるたびに新しいオブジェクトを作成します。したがって、への1つの呼び出しの結果はgetComparator別個のオブジェクトになり、したがって、別の呼び出しの結果と等しいとは見なされません。

同等性テストがtrueを返すようにコードを変更する2つの可能な方法を考えることができます。

  1. コンパレータを1回だけ作成し、この同じオブジェクトをから返します getComparator。これには、次のような変更が含まれmyClassます。

        private static Comparator<ListItem> cmp = new Comparator<myOtherObject>() {
           public int compare(myOtherObjectitem1, myOtherObjectitem2) {
                return (Integer.valueOf(myOtherObject.getRating()).compareTo(Integer.valueOf(myOtherObject.getRating())));
            }
        };
    
        static Comparator<ListItem> getComparator() {
            return cmp;
        }
    
  2. 明示的なequals()実装を提供します(したがってhashCode()、理想的には実装も提供します)。次に、どのオブジェクトがコンパレータの1つと等しいと見なされるかを正確に制御できます。これは、匿名の内部クラスではなく、コンパレータの具象クラスを定義する方がはるかに簡単な場合があります。


しかし、結局のところ、あなたのアプローチが正しくないのではないかと心配しています。2つのコンパレータが互いに等しいとはどういう意味ですか?これはデータクラス以外のあいまいな概念だと思いますObject.equals。このためのメソッドを使用することを躊躇します。

(たとえば、「リストを同じ順序で並べ替える」という意味の場合は、コンパレータクラスisEquivalentSortOrderなどにメソッドを追加します。これにより、依存することなく、意味を正確に指定できます。 「同じであること」の羊毛の定義。)

于 2012-12-03T12:36:54.280 に答える
0

次のようなmyClass静的変数の内部を作成しないのはなぜですか。Comparator

class myClass{
    public static Comparator<ListItem> = new Comparator<myOtherObject>() {
        public int compare(myOtherObjectitem1, myOtherObjectitem2) {
            ...
        }
    };
}
于 2012-12-03T12:39:25.013 に答える