生成通用列表的“可组合未来”的“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;
        }