停止供应商内部的CompletableFuture链接

我有这样的手术

public void createFuture() {
    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 5);
    future.thenApply(i -> {
        if (i == 5) {
            System.out.println("hello,i equals to 5 so expensive operations are unnecessary");
        }
        return i;
    }).thenApply(i -> {
        if (i != 5) {
            System.out.println("Expensive operation");
        }
        return i;
    }).thenApply(i -> {
        if (i != 5) {
            System.out.println("Expensive operation");
        }
        return i;
    }).thenApply(i -> {
        if (i != 5) {
            System.out.println("Expensive operation");
        }
        return i;
    }).thenApply(i -> {
        if (i != 5) {
            System.out.println("Expensive operation");
        }
        return i;
    });

}

在第一块中,我检查了一些条件(i == 5),如果为真,则不需要其余操作。我不想抛出异常来取消其余部分,因为这不是例外情况。除了将布尔值传递给每个操作之外,还有其他好方法吗?

yudian1988 回答:停止供应商内部的CompletableFuture链接

CompletableFuture.thenCompose()应该可以解决问题。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;

class Scratch {

  public static void main(String[] args) throws ExecutionException,InterruptedException {
    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 5);
    CompletableFuture<Integer> composed = future.thenCompose(number -> {
      if (number == 5)
        return simpleFuture(number);
      else
        return complexFuture(number);
    });
    System.out.println(composed.get());
  }

  private static CompletionStage<Integer> complexFuture(Integer number) {
    return CompletableFuture.completedFuture(number)
        .thenApply(i -> {
          System.out.println("I am expensive");
          return i;
        });
  }

  private static CompletableFuture<Integer> simpleFuture(Integer number) {
    return CompletableFuture.completedFuture(number)
        .thenApply(i -> {
          System.out.println("I am cheap");
          return i;
        });
  }
}
,

CompletableFuture没有支持条件语句的机制。在您的情况下,可以通过i != 5CompletableFuture的所有任务提取到一个thenCompose中来简化代码。

其他解决方法是创建地图,对其进行过滤并使用它创建可完成的未来:

Map<Predicate<Integer>,Runnable> m = Map.of(
    integer -> integer == 5,() -> System.out.println("Task 1"),integer -> integer != 5,() -> System.out.println("Task 2"),() -> System.out.println("Task 3")
);
CompletableFuture[] runnables = m.entrySet().stream()
    .filter(e -> e.getKey().test(5))
    .map(Map.Entry::getValue)
    .map(CompletableFuture::runAsync)
    .toArray(CompletableFuture[]::new);
CompletableFuture composed = CompletableFuture.allOf(runnables);

这里我正在创建地图Predicate-> Runnable。然后,我过滤掉所有不满足谓词的对,并将可运行对象包装到CompletableFuture中。 composed的末尾是CompletableFuture,它由所有所需的可运行对象组成。

本文链接:https://www.f2er.com/2831838.html

大家都在问