问题描述
我正在尝试理解 CompletableFuture
API,但遇到了以下问题。
allOf
本身只返回一个 CompletableFuture<void>
,因此与一个名为 allResultsOf
的函数有一个稍微更好的接口才有意义:这样的函数应该是通用的,并作为参数接收List<CompletableFuture<T>>
类型的对象并返回 CompletableFuture<List<T>>
我对这个函数声明的尝试是:
public static CompletableFuture<List<T>> allResultsOf(List<CompletableFuture<T>> CompletableFutures) {
CompletableFuture<Void> allFutures = CompletableFuture
.allOf(CompletableFutures.toArray(new CompletableFuture[CompletableFutures.size()]));
CompletableFuture<List<T>> allCompletableFuture = allFutures.thenApply(
future -> {
return CompletableFutures.stream()
.map(CompletableFuture -> CompletableFuture.join())
.collect(Collectors.toList());
});
return allCompletableFuture;
}
但是,在我的(附加的)示例代码段中,这个函数给出了这个编译错误:
错误:类型不兼容:List allCompletableFuture = allResultsOf(CompletableFutures);
我不确定这里有什么问题
import java.util.*;
import java.util.stream.*;
import java.lang.*;
import java.io.*;
import java.util.concurrent.*;
// The main method must be in a class named "Main".
class Main {
static class Test {
private ExecutorService executor;
public Test(ExecutorService es) {
executor = es;
}
public class GreetHolder {
private String greet;
public GreetHolder(String greet) {
this.greet = greet;
}
public String getGreet() {
return greet;
}
public void setGreet(String greet) {
this.greet = greet;
}
public String toString() {
return getGreet();
}
}
private CompletableFuture<GreetHolder> getGreeting(String lang) {
return CompletableFuture.supplyAsync( () -> {
try {
System.out.println("Task execution started for lang =" + lang);
Thread.sleep(200);
System.out.println("Task execution stopped for lang =" + lang);
} catch (InterruptedException e) {
e.printstacktrace();
}
return new GreetHolder(getGreet(lang));
},executor);
}
public String getGreet(String lang) {
if (lang.equals("EN")) {
return "Hello";
} else if (lang.equals("ES")) {
return "Hola";
} else if (lang.equals("SN")) {
return "Ayubovan";
} else {
throw new IllegalArgumentException("Invalid lang param");
}
}
public CompletableFuture<List<Test.GreetHolder>> run() {
List<String> langList = Arrays.asList("EN","ES","SN"); //,"EX");
List<CompletableFuture<Test.GreetHolder>> CompletableFutures =
langList.stream().map(lang -> getGreeting(lang))
//.map(CompletableFuture::join);
.collect(Collectors.toList());
// return CompletableFutures;
CompletableFuture<Void> allFutures = CompletableFuture
.allOf(CompletableFutures.toArray(new CompletableFuture[CompletableFutures.size()]));
CompletableFuture<List<GreetHolder>> allCompletableFuture = allFutures.thenApply(
future -> {
System.out.println(String.format("%s <- future",future));
return CompletableFutures.stream()
.map(CompletableFuture -> CompletableFuture.join())
.collect(Collectors.toList());
});
System.out.println(String.format("%s <- allCompletableFuture",allCompletableFuture));
//return allCompletableFuture;
CompletableFuture CompletableFuture = allCompletableFuture.thenApply(
greets -> {
return greets
.stream()
.map(GreetHolder::getGreet)
.collect(Collectors.toList());
});
return CompletableFuture;
}
public static CompletableFuture<List<T>> allResultsOf(List<CompletableFuture<T>> CompletableFutures) {
CompletableFuture<Void> allFutures = CompletableFuture
.allOf(CompletableFutures.toArray(new CompletableFuture[CompletableFutures.size()]));
CompletableFuture<List<T>> allCompletableFuture = allFutures.thenApply(
future -> {
System.out.println(String.format("%s <- future",future));
return CompletableFutures.stream()
.map(CompletableFuture -> CompletableFuture.join())
.collect(Collectors.toList());
});
return allCompletableFuture;
}
public CompletableFuture<List<Test.GreetHolder>> run_tidier() {
List<String> langList = Arrays.asList("EN","EX");
List<CompletableFuture<Test.GreetHolder>> CompletableFutures =
langList.stream().map(lang -> getGreeting(lang))
//.map(CompletableFuture::join);
.collect(Collectors.toList());
CompletableFuture<List<GreetHolder>> allCompletableFuture = allResultsOf(CompletableFutures);
System.out.println(String.format("%s <- allCompletableFuture",allCompletableFuture));
CompletableFuture CompletableFuture = allCompletableFuture.thenApply(
greets -> {
return greets
.stream()
.map(GreetHolder::getGreet)
.collect(Collectors.toList());
});
return CompletableFuture;
}
}
public static void main(String[] args) throws InterruptedException,ExecutionException {
ExecutorService pool = Executors.newFixedThreadPool(2);
Test t = new Test(pool);
System.out.println(String.format("%s world!",t.getGreet("EN")));
CompletableFuture cf = t.run();
System.out.println(String.format("%s <- cf",cf.get()));
}
}
解决方法
正如 Matt Timmermans 所建议的,您需要一个类型变量。
将 allResultsOf
更改为此编译:
public static <T> CompletableFuture<List<T>> allResultsOf(List<CompletableFuture<T>> completableFutures) {
CompletableFuture<Void> allFutures = CompletableFuture
.allOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()]));
CompletableFuture<List<T>> allCompletableFuture = allFutures.thenApply(
future -> {
System.out.println(String.format("%s <- future",future));
return completableFutures.stream()
.map(completableFuture -> completableFuture.join())
.collect(Collectors.toList());
});
return allCompletableFuture;
}