3 回答
TA贡献1818条经验 获得超11个赞
实例化和抛出大量异常可能会变得相当昂贵,这就是为什么它们应该仅限于特殊情况。相反,您可以使用Optional来控制流:
func = (value) -> Optional.of(value + 5);
func = func.andThen((optionalValue) -> {
// Instead of throwing an exception, return an empty Optional
System.out.println("Log the failure");
return Optional.empty();
});
func = func.andThen((optionalValue) -> {
optionalValue.map((value) -> { // This lambda will only execute if optionalValue is not empty
System.out.println("Reached last function !");
return value; // map wraps this in an Optional
});
});
// Finally, unwrap the value. Optional provides a number of ways to do this, depending on how you want to handle failure/empty
func = func.andThen((optional) -> optional.orElse(...));
executeFunction(func);
TA贡献1877条经验 获得超1个赞
您可以为函数/可运行对象编写一个包装器,在任务失败时记录并退出。就像这样:
class Runnables
{
public static Runnable trying(Runnable... runnables)
{
return () ->
{
int successes = 0;
try
{
for(Runnable runnable : runnables)
{
runnable.run();
successes++;
}
}
catch(Throwable t)
{
logger.error("Exception thrown from "+successes+"th runnable: ",t);
}
};
}
}
然后:
private static void executeFunction(Runnable... runnables)
{
CompletableFuture.supplyAsync(Runnables.trying(runnables));
}
TA贡献1891条经验 获得超3个赞
您可以通过使用CompletableFuture.thenApply
方法来获得所需的行为。例如:
public class Answer {
public static void main(String[] args) {
Function<Integer, Integer> fn0 = v -> v + 5;
Function<Integer, Integer> fn1 = v -> {
throw new RuntimeException("failed");
};
Function<Integer, Integer> fn2 = v -> {
System.out.println("Reached last function !");
return v;
};
CompletableFuture.supplyAsync(() -> fn0.apply(100))
.thenApply(fn1)
.thenApply(fn2)
.exceptionally(throwable -> {
// next line prints the exception thrown by fn1, wrapped in java.util.concurrent.CompletionException
System.out.println("Failed with error: " + throwable);
return 0; // default value, used when exception is thrown
});
}
}
基本上,CompletableFuture链将被“开箱即用”的异常中断,因此不需要额外的处理。
或者,如果您想要更通用的方法:
public class Answer {
public static void main(String[] args) {
executeAsync(() -> stepOne(100))
.thenApply(Answer::stepTwo)
.thenApply(Answer::finalStep)
.exceptionally(Answer::handleException);
}
private static CompletableFuture<Integer> executeAsync(Supplier<Integer> task) {
return CompletableFuture.supplyAsync(task::get);
}
private static Integer stepOne(Integer value) {
return value + 5;
}
private static Integer stepTwo(Integer value) {
throw new RuntimeException("failed");
}
private static Integer finalStep(Integer value) {
System.out.println("Reached last function !");
return value;
}
private static Integer handleException(Throwable throwable) {
// next line prints the exception thrown by any step before, wrapped in java.util.concurrent.CompletionException
System.out.println("Failed with error: " + throwable);
return 0; // default value
}
笔记:
使用thenApply您可以根据需要链接任意数量的函数调用
在最后一个示例中,同一类中的方法可以替换为其他类中的方法(不一定是静态类)
添加回答
举报