通常、CompletableFutureを使用すると、結果が利用可能になるとすぐに、thenApplyまたは他のメソッドを呼び出して何かを実行します。しかし、今私は肯定的な結果を得てからすべての結果を無視するまで結果を処理したいという状況があります。Javaでは、CompletableFuturesをどのように処理して、完了した最初の望ましい結果が得られますか?
私は、CompletableFuture.anyOfを使うことができました(リストを配列に変換してanyOfを呼び出す必要はありません)。しかし、それは私が望むものではありません。私は最初の結果を得たい、それが望ましい結果をもたない場合、望ましい結果が得られるまで、2番目に利用可能な結果を処理したいと思います。ここで
はすべての結果を通過し、それが9よりも大きい見つかった最初の値を返す単純な例を示します(これは私の本当の仕事ではないことに注意してください。これは単純な例です。)
public Integer findFirstGt9(List<CompletableFuture<Integer>> results) {
for(CompletableFuture<Integer> result : results) {
Integer v = result.get();
if(v > 9)
return v;
}
return null;
}
もちろん、その例は、結果が完成したときに見るのではなく、最初からの結果を通っています。ですから、私が欲しいものを達成するものがありますが、はるかに複雑なコードがあります。
public Integer findFirstGt9(List<CompletableFuture<Integer>> results) {
AtomicInteger finalResult = new AtomicInteger();
CountDownLatch latch = new CountDownLatch(results.size());
for(CompletableFuture<Integer> result : results) {
result.whenComplete((v,e) -> {
if(e!=null) {
Logger.getLogger(getClass()).error("",e);
} else if(v > 9) {
finalResult.set(v);
while(latch.getCount() > 0)
latch.countDown();
return;
}
latch.countDown();
});
}
latch.await();
if(finalResult.get() > 9)
return finalResult.get();
return null;
}
ここで私はこれを行うことができますか?
public Integer findFirstGt9(List<CompletableFuture<Integer>> results) {
Iterator<Integer> resultIt = getResultsAsAvailable(results);
for(; resultIt.hasNext();) {
Integer v = resultIt.next();
if(v > 9)
return v;
}
return null;
}
あるいはさらに良い:
public Integer findFirstGt9(List<CompletableFuture<Integer>> results) {
return getFirstMatch(results, r -> {return r > 9;});
}