2017-06-13 9 views
6

だが、私はこの不可欠コードを持っているとしましょう:関数リストをJava 8の値に適用する方法は?

List<Function<T, T>> functions = ... 
    T value = ... 
    for (Function<T, T> function : functions) { 
     value = function.apply(value); 
    } 

私は(Scalaで何倍のような)機能的なスタイルでこれを書くにはどうすればよいですか?

+1

あなたは値を入力して '#forEach'を' function'リストにすることができますが、実際には何も得られません(とにかく機能的ではありません)。全体的にコードはそれが何であるかに見えますが、javaは命令的言語です。 – Rogue

+1

[Java-8での関数の配列リストの操作](https://stackoverflow.com/questions/30274124/working-with-an-arraylist-of-functions-in-java-8)これは役に立ちます –

+4

ルックスクローズ[this one](https://stackoverflow.com/q/32338553/2711488)... – Holger

答えて

10

これはちょうど...あなたは、単一の機能にそれらを減らして、それを適用することができConsumerのために、数時間前に頼まれています

@SafeVarargs 
private static <T> Function<T, T> combineF(Function<T, T>... funcs) { 
    return Arrays.stream(funcs).reduce(Function.identity(), Function::andThen); 
} 
+4

意味的に同じですが、 '.reduce(Function :: andThen).orElse(Function.identity())'はやや効率的な関数を生成します。 – Holger

+0

@Holder '.reduce(Function :: andThen).orElseGet(Function :: identity)'を使用する際に問題はありますか? – srborlongan

+1

@ srborlonganについては、先に説明しました。https://stackoverflow.com/questions/44261253/when-i-need-to-use-optional-orelsegetget-over-optional-orelse/44261755#44261755 – Eugene

1

ここだけの楽しみのためにユージンの答え、の変種だ

public static <T> Function<T, T> combine(List<Function<T, T>> functions) { 
    return new Object() { 
     Function<List<Function<T, T>>, Function<T, T>> combiner = list -> 
      list.size() == 1 ? list.get(0) : 
      list.get(0).andThen(this.combiner.apply(list.subList(1, list.size()))); 
    }.combiner.apply(functions); 
} 

これは、属性が再帰的ラムダである匿名の内部クラスを作成します。この属性の名前はcombinerで、という高次関数です。関数のリストを引数として受け取り、結果として関数を返します。この高次関数は、リストに要素が1つのみ含まれている場合はリストの最初の関数を返し、リストの最初の関数にはandThenを適用し、次のサブリストを持つ高次関数への再帰呼び出しの結果を返します2番目の要素から始まる関数。

再帰ラムダはクラスの属性としてしか定義できないため、匿名の内部クラスが必要です。

これは、リストをストリーミングして、Function::andThenバイナリ演算子で減らすよりも複雑です。さらに、再帰ラムダは自由ではありません。再帰呼び出しにスタックを使用します。

+0

ラムダのためのフィールドを作成する以外に、Java 8の別の(あまり直感的でない)方法は、[Yコンビネータ](http://rosettacode.org/wiki/Y_combinator#Java)を使うことです。 – srborlongan

+1

@srborlonganまたは[trampolines](http://raganwald.com/2013/03/28/trampolines-in-javascript.html)... –

関連する問題