[英]Chaining completable futures based on conditions
我有一堆返回CompletableFuture的方法,我想以一種特定的方式鏈接
package com.sandbox;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.stream.IntStream;
public class SandboxFutures {
public CompletableFuture<Integer> generateRandom(int min, int max) {
return CompletableFuture.supplyAsync(() -> {
if (min >= max) {
throw new IllegalArgumentException("max must be greater than min");
}
Random r = new Random();
return r.nextInt((max - min) + 1) + min;
});
}
public CompletableFuture<String> printEvenOrOdd(int result) {
return CompletableFuture.supplyAsync(() -> {
if (result % 2 == 0)
return "Even";
else
return "Odd";
});
}
public CompletableFuture<Integer> findFactorial(int evenNumber) {
return CompletableFuture.supplyAsync(() -> {
if (evenNumber <= 0) {
return 0;
}
return IntStream.rangeClosed(2, evenNumber).reduce(1, (x,y) -> x*y);
});
}
public CompletableFuture<Integer> convertToNearestEvenInteger(int oddNumber) {
return CompletableFuture.supplyAsync(() -> {
if (oddNumber <= 0) {
return 2;
}
return oddNumber+1;
});
}
}
我正在嘗試根據以下規則將它們合並,
Even
,如果是奇數則打印Odd
findFactorial
使用隨機數調用findFactorial
convertToNearestEvenInteger
查找最接近的偶數 我不太清楚如何進行條件鏈接和異常處理。 一些示例或代碼片段可能會有所幫助。
您可以使用thenCompose()
:
CompletableFuture<Integer> n = generateRandom(1, 100)
.thenCompose(i -> printEvenOrOdd(i)
.thenCompose(s -> s.equals("Even")
? findFactorial(i)
: convertToNearestEvenInteger(i)));
System.out.println(n.get());
但是,當生成大偶數時,階乘方法不能存儲大於int
任何值,因此您需要對其進行更新。
printEvenOrOdd
的寫入方式使其變得比所需的難度更大。 問題是它不打印單詞“ Even”或“ Odd”,而是返回它,這意味着原始result
丟失了。 其余步驟依賴於實際數字。 要解決此問題,可以使用調用printEvenOrOdd
並使用.thenApply(__ -> result)
再恢復原始數字。 它看起來像這樣:
System.out.println(
generateRandom(1, 100)
.thenCompose(result ->
printEvenOrOdd(result)
.thenAccept(System.out::println)
.thenApply(__ -> result)
)
.thenCompose(result ->
result % 2 == 0
? findFactorial(result)
: convertToNearestEvenInteger(result)
)
.join()
);
更好的解決方案是將printEvenOrOdd
的定義更改為:
public CompletableFuture<Integer> printEvenOrOdd(int result) {
return CompletableFuture.supplyAsync(() -> {
System.out.println(result % 2 == 0 ? "Even" : "Odd");
return result;
});
}
這將使鏈接步驟3和4變得更加容易:
System.out.println(
generateRandom(1, 100)
.thenApply(this::printEvenOrOdd)
.thenCompose(result ->
result % 2 == 0
? findFactorial(result)
: convertToNearestEvenInteger(result)
)
.join()
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.