3

私はcompletable先物として枠3件のダウンロードを、持っているとしますCompletableFuture:複数のCompletableFuturesに関数を適用するにはどうすればよいですか?

CompletableFuture<Doc> dl1 = CompletableFuture.supplyAsync(() -> download("file1")); 
    CompletableFuture<Doc> dl2 = CompletableFuture.supplyAsync(() -> download("file2")); 
    CompletableFuture<Doc> dl3 = CompletableFuture.supplyAsync(() -> download("file3")); 

そして、それらのすべてが同じよう

CompletableFuture<String> s1 = dl1.thenApply(Doc::getFilename); 
    CompletableFuture<String> s2 = dl2.thenApply(Doc::getFilename); 
    CompletableFuture<String> s3 = dl3.thenApply(Doc::getFilename); 

を処理する必要があり、適用される複数の機能を想像することができ、すべてで平行。

DRYの原則によれば、この例は不適切と思われます。だから私は、並列に3回実行されるワークフローを1つだけ定義するソリューションを探しています。

これはどのように達成できますか?

私はallOfを試しましたが、それには2つの問題があります.1)ブロックが開始され、2)戻り値の型はrunのものしか扱えません。もちろん

+4

は、まずダウンロードして呼び出し、新しいメソッドを宣言すると、あなたが持っているだろうより多くのの世話をする必要があるかもしれませんGetFilename –

+1

を取得するには、ファイルをリストに入れてから繰り返し処理することを考えましたか? – Ash

答えて

5
Stream.of("file1", "file2", "file3") // or your input in any other format, that can easily be transformed to a stream... 
     // .parallel() // well... depends... 
     .map(s -> CompletableFuture.supplyAsync(() -> download(s))) 
     .map(dl -> dl.thenApply(Doc::getFilename)) 
     .map(CompletableFuture::join) // if you want to have all the results collected 
     .collect(Collectors.toList()); 

、二つmap -callsを組み合わせることができます。しかし少なくともあなたはx回すべてを書きません...もしコレクションがListになっていないのなら、その上で何か他のものを呼び出すこともできます。 .forEach(System.out::println).forEachには、応答が利用可能になるとすぐに消費者が呼び出されるという利点があります。

またはクラシック:ちょうどあなたの入力のためのループ、リスト/配列を使用していますが、ストリーム

関連する問題