2016-05-02 22 views
1

私は匿名の内部クラスとしてコンパレータを作成していますが、その最良の方法はわかりません。私はコード内で一度しか作成していませんが、リストをソートするたびにその内部クラスが作成されているかどうかはわかりません。たとえば、アプリケーションで、コンパレータを10回使用してソートメソッドを呼び出す場合、10個の追加クラスが作成されますか?匿名の内部クラス - コレクションsort

Collections.sort(originalList, new Comparator<User>() { 
    @Override 
    public int compare(User o1, User o2) { 
     int value1 = o1.getPropertyCode().compareTo(o2.getPropertyCode()); 
     if (value1 == 0) { 
      int value2=o1.getPropertyValue().compareTo(o2.getPropertyValue()); 
      return value2; 
     } 
     return value1; 
    } 
}); 

VS

Collections.sort(originalList、新しいSomeComparator())。

+8

コードを新しいインスタンスを作成しません千の言葉の価値があります!私たちに教えてください! – MrSimpleMind

+2

「10個の追加クラスを作成する」とは、10個のインスタンスを意味する場合、答えは「はい」です。 (これは 'new'キーワードの意味です) –

+5

...しかし、実際には10の余分なインスタンスを実行します*実際にはパフォーマンスに顕著な影響を与えますか?特定の状況下では、おそらく;一般的に、ナ。 –

答えて

3

匿名クラスはコンパイラによって通常のクラス定義に変換され、実際にはOutterClass$1のような名前が付けられますが、そのクラスでそのクラスを参照することはできませんが、それは常に同じであることを確認するためにはnew Object() {}.class.getName()などです。あなたのコードが問題の行に当たると、明示的な名前を付けるかどうかにかかわらず、1つのクラスだけを使用します。あなたの2つのオプションは基本的に同じです。

Collections.sort(originalList, newまでのコード行を読むときは、毎回newが新しいインスタンス(クラスではありません)を作成することに注意してください。私。生成されたコンパレータ・オブジェクトは決して異なっていないので、メモリを割り当て、そのオブジェクトを初期化します。

次のいずれかのようなので、フィールドで一度作成されたコンパレータを記憶しているしたいと思うだろう何(かのようにJavaの独自のソースでString.CASE_INSENSITIVE_ORDER

private static final Comparator<User> USER_COMPARATOR = new Comparator<User>() { 
    @Override 
    public int compare(User o1, User o2) { 
     int value1 = o1.getPropertyCode().compareTo(o2.getPropertyCode()); 
     if (value1 == 0) { 
      int value2=o1.getPropertyValue().compareTo(o2.getPropertyValue()); 
      return value2; 
     } 
     return value1; 
    } 
}; 
private void someCode() { 
    Collections.sort(originalList, USER_COMPARATOR); 
} 

またはJava 8であなたは、ラムダにそれを回すことができます

(気づく行方不明 new)もたび

Collections.sort(originalList, (o1, o2) -> { 
    int value1 = o1.getPropertyCode().compareTo(o2.getPropertyCode()); 
    if (value1 == 0) { 
     int value2=o1.getPropertyValue().compareTo(o2.getPropertyValue()); 
     return value2; 
    } 
    return value1; 
}); 
+0

あなたはラムダにそれを回す場合は、あなたにもはるかにコンパクト '(ユーザー:: getPropertyCode).thenComparing(ユーザー:: getPropertyValueを)'の比較を書くかもしれません。 –

+0

優秀で、これがStringクラスで使用されているかどうかはわかりませんでした。これは、デザインパターンのように、より一般的にする必要があります。その記憶は、余分なクラスでは常に問題ではありませんが、私の場合はそれが役に立つと確信しています。 – user2296988

+0

@LouisWassermanの欠点は、これがラムダのような静的フィールドにならず、コードが実行されるたびに生成されることです。おそらくJITがそれに手を当てた後ではないでしょうが、とにかく私はそれを静的フィールドに割り当てます – zapl

0

です。メソッドでコンパレータを使用している場合は、新しい呼び出しがインスタンス化されます。さらに、コンパレータには包含クラスへの参照が含まれます。

一方、匿名の内部クラスを静的フィールドとして定義すると、クラスローダーごとに1つしか存在しません。

+0

静的フィールドとしてどのように宣言しますか?静的な初期化ブロックのように? – user2296988

関連する問題