web-dev-qa-db-ja.com

Java 8ストリームを使用する場合の新しいオブジェクトのインスタンス化

後者の読みやすさのわずかな改善以外に、次の構造の使用に違いはありますか?

someList.stream().map(item -> new NewClass(item)).collect(Collectors.toList());

someList.stream().map(NewClass::new).collect(Collectors.toList());
37
ShellDragon

通常、違いはありません。 NewClass::newは、ラムダバージョンの場合より少ないバイトコードを生成します。自動生成されたプライベートメソッドは、ラムダ本体からJavaコンパイラによって作成され、NewClass:newはコンストラクタメソッドハンドルに直接リンクします。したがって、メソッド参照を使用すると、クラスファイルのサイズがわずかに小さくなる場合があります。ただし、パフォーマンスに大きな違いはありません。

もう1つの違いは、メソッド解決手順です。特定の例には適用されませんが、他のコードにも適用される場合があります。たとえば、2つのコンストラクターがあります。

public NewClass(String a) {...}
public NewClass(String a, String b) {...}

そして、機能的なインターフェイスを受け入れるいくつかのメソッドがあります:

public myMethod(Function<String, NewClass> fn) {...}

次に、ラムダまたは機能インターフェイスの両方で呼び出すことができます:

myMethod(str -> new NewClass(str));
myMethod(NewClass::new);

しかし、後で次のような同じ名前の新しいメソッドを追加するとします。

public myMethod(BiFunction<String, String, NewClass> fn) {...}

そうすると、メソッド参照呼び出しはあいまいになり、NewClass::newが両方のコンストラクターに一致するため、コンパイルエラーが発生しますが、ラムダはまだあいまいではありません。

42
Tagir Valeev