根据条件链接可完成的期货
Chaining completable futures based on conditions
我有一堆 return 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
的书写方式使它比需要的更难。问题是它不打印这个词"Even"或"Odd",它returns它,这意味着原来的 result
丢失了。其余步骤取决于实际数字。要解决此问题,您可以使用 call 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()
);
我有一堆 return 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
- 如果号码是偶数,用随机数 调用
- 如果数字是奇数通过
convertToNearestEvenInteger
找到最近的偶数
findFactorial
我不太清楚如何进行条件链接和异常处理。一些示例或代码片段可能会有所帮助。
您可以使用 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",它returns它,这意味着原来的 result
丢失了。其余步骤取决于实际数字。要解决此问题,您可以使用 call 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()
);