我有一堆返回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;
});
}
}
我正在尝试根据以下规则将它们组合在一起,
- 生成一个介于 1 和 100 之间的随机数
- 如果数字是偶数打印
Even
,如果是奇数打印Odd
- 如果号码是偶数,则用随机数呼叫
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
的方式使其比需要的更加困难。问题是它不会打印单词"偶数"或"奇数",而是返回它,这意味着原始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()
);