我有一堆返回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
convertToNearestEvenInteger
查找最接近的偶数我不太清楚如何进行条件链接和异常处理。一些示例或代码片段可能会有所帮助。
答案 0 :(得分:1)
您可以使用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
的任何内容,因此您需要对其进行更新。
答案 1 :(得分:0)
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()
);