7

Javaを機能的に構成する最良の方法は、FunctionConsumerですか? たとえば、Function<Object, String> fConsumer<String> cの場合、f.andThen(c)を実行すると自然な感じになりますが、それはインターフェイスの仕組みではありません。私が見Java関数とコンシューマを合成する

2つのオプションがあるのいずれかFunction<String, Void> cConsumer<String> cを交換したり、BiConsumer<Function<Object, String>, String> cConsumer<String> cを変更し、

accept(Function<Object, String> f, Object o) { 
    String thing = f.apply(o); 
    //do something with thing 
} 

が、他のより良いこれらの一つでありますか?より良い方法がありますか?

+0

これはユースケースを提供できますか? – Tunaki

+0

私は自分自身の 'Consumer'クラスを作成したいと思います。約10行のコードが必要です。 –

+1

@Tunaki単純なユースケースは、文字列の異なる方法(関数)としてシリアル化したいオブジェクトを持っていて、それをデータベースや端末(消費者)のようにどこかに出力したい場合でしょう。 – kag0

答えて

10

これはあなたがやろうとしていることですか?

Consumer<Object> composed = o -> c.accept(f.apply(o)); 

あなた自身がこの問題に多くを直面見つけた場合、あなたはこれを行うには、静的メソッドを作ることができます(しかし、それは本当に価値がある?):

static<T,R> Consumer<T> applyAndAccept(Function<? super T,? extends R> f, Consumer<R> c){ 
    return t -> c.accept(f.apply(t)); 
} 
+2

時にはそれは価値があります。単一の退屈なラムダの代わりに2つのクールメソッド参照を使用できます。メソッド参照がインスタンスにバインドされ、インスタンスが非最終変数に格納されている場合、ラムダのバージョンは実際には不器用に見えます。このコンテキストでは、メソッド参照型が自動的に推測されるため、提案された静的メソッドは存在しないデフォルトメソッド 'andThen(Consumer)'よりも優れています。 –

+1

@TagirValeev私は、メソッド参照を使用する能力は大きなプラスだと思います。私はちょうど '機能' - 'コンシューマー'の状況に十分に踏み込んでいないのですが、おそらく他の人はそうしています。私がいつもぶつかるのは、 'Function'と' Predicate'を作成する必要があることです。 – Misha

0

は、このないですmapおよびforEach

public void test() { 
    Function<Object, String> f = (Object t) -> t.toString(); 
    Consumer<String> c = (String t) -> { 
     System.out.println(t); 
    }; 
    List<Object> data = new ArrayList<>(); 
    data.stream().map(f).forEach(c); 
} 
+1

あなたのストリームにはターミナル操作がないので、何も実行しません。ストリーム処理も 'Consumer'を使う例です。彼らは他の場所でも便利です。 –

+0

@TagirValeev - 興味深いことに、 '.toArray()'を追加することはそれを修正するようです。 – OldCurmudgeon

+2

これは 'peek'の悪用です。 'c'がスレッドセーフでない場合は、' .map(f).forEach(c) 'または' .map(f).forEachOrdered(c) 'を実行してください。 – Misha

0

独自のコードでjava.util.function.Functionインターフェイスのコピーを作成できます。それをConsumableFunctionと呼び、すべてのデフォルトメソッドのパラメータタイプを変更し、FunctionからConsumableFunctionに値を返します。次に、次のデフォルト関数を追加します。

default Consumer<T> atLast(Consumer<R> consumer) { 
    Objects.requireNonNull(consumer); 
    return (T t) -> consumer.accept(apply(t)); 
} 

ここで、すべての関数implmementが代わりにConsumableFunctionを実装するようにします。次に、次のようなコードを書くことができます:

Consumer<A> consumerForA = functionFromAToB 
    .andThen(functionFromBToC) 
    .andThen(functionFromCToD) 
    .atLast(consumerForD); 
関連する問題