生成通用列表的“可组合未来”的“all Of”的通用版本
generic version of `allOf` that results a `ComposableFuture` of a generic list
我试图理解 CompletableFuture
API,但我遇到了以下问题。
allOf
本身只是 return 一个 CompletableFuture<void>
,所以只有一个稍微好一点的接口和一个叫做 allResultsOf
的函数才有意义:这样的函数应该是泛型,并接收 List<CompletableFuture<T>>
和 return 类型的对象作为参数对象 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;
}
但是,在我的(附加的)示例片段中,这个函数给出了这个编译错误:
error: incompatible types: List<CompletableFuture<Test.GreetHolder>>
cannot be converted to List<CompletableFuture<?>>
CompletableFuture<List> allCompletableFuture = allResultsOf(completableFutures);
我不确定这里的问题是什么
示例代码(摘自here):
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", "ES", "SN"); //, "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;
}
我试图理解 CompletableFuture
API,但我遇到了以下问题。
allOf
本身只是 return 一个 CompletableFuture<void>
,所以只有一个稍微好一点的接口和一个叫做 allResultsOf
的函数才有意义:这样的函数应该是泛型,并接收 List<CompletableFuture<T>>
和 return 类型的对象作为参数对象 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;
}
但是,在我的(附加的)示例片段中,这个函数给出了这个编译错误:
error: incompatible types: List<CompletableFuture<Test.GreetHolder>> cannot be converted to List<CompletableFuture<?>> CompletableFuture<List> allCompletableFuture = allResultsOf(completableFutures);
我不确定这里的问题是什么
示例代码(摘自here):
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", "ES", "SN"); //, "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;
}