3

Java 8 ストリームを使用していると、複数ステートメントのラムダ式をリファクタリングする必要があることがよくあります。これを簡単な例で説明します。次のコードを書き始めたとします。

Stream.of(1, 3).map(i -> {
    if (i == 1) {
        return "I";
    } else if (i == 3) {
        return "E";
    }
    return "";
}).forEach(System.out::println);

今、私はmap呼び出しの大きなラムダ式があまり好きではありません。したがって、そこからリファクタリングしたいと思います。Functionクラスでのインスタンスを作成するか、2 つのオプションが表示されます。

private static Function<Integer, String> mapper = i -> {
    if (i == 1) {
        return "I";
    } else if (i == 3) {
        return "E";
    }
    return "";
};

次のように使用します。

Stream.of(1, 3).map(mapper).forEach(System.out::println);

または、単にメソッドを作成します。

private static String map(Integer i) {
    if (i == 1) {
        return "I";
    } else if (i == 3) {
        return "E";
    }
    return "";
}

メソッド参照を使用します。

Stream.of(1, 3).map(Test::map).forEach(System.out::println);

明らかな好みの問題は別として、どちらのアプローチにも利点や欠点はありますか?

たとえば、メソッド参照の場合、スタック トレースが読みやすくなることはわかっていますが、これは小さな利点です。

4

2 に答える 2

6

私が気付いていない追加の魔法がない限り、現在のラムダ実装は、非キャプチャラムダを静的メソッドに脱糖し、ラムダインスタンスをキャッシュします。同じことを明示的に行う (static finalラムダへの参照) ことで、基本的にその暗黙的な作業を複製することになるため、同じものへの 2 つのキャッシュされた参照を作成することになります。また、ラムダ インスタンスの遅延初期化を無効にしています。これは、そうでなければ無料で取得できます。

これが、私がメソッド参照のみを好む理由です。これは、記述が簡単で、より慣用的であり、実装に関してもより軽量であるように思われます。

于 2015-08-31T11:47:24.550 に答える