Java 如何访问传递给CompletableFuture allOf的已完成期货?

Java 如何访问传递给CompletableFuture allOf的已完成期货?,java,java-8,completable-future,Java,Java 8,Completable Future,我正在努力掌握Java8的未来。我怎样才能加入这些人,并返回他们后,“allOf”。下面的代码不起作用,但让您了解我的尝试 在javascript ES6中,我会这样做 Promise.all([p1, p2]).then(function(persons) { console.log(persons[0]); // p1 return value console.log(persons[1]); // p2 return value }); 到目前为止我在Ja

我正在努力掌握Java8的未来。我怎样才能加入这些人,并返回他们后,“allOf”。下面的代码不起作用,但让您了解我的尝试

在javascript ES6中,我会这样做

Promise.all([p1, p2]).then(function(persons) {
   console.log(persons[0]); // p1 return value     
   console.log(persons[1]); // p2 return value     
});
到目前为止我在Java方面的努力

public class Person {

        private final String name;

        public Person(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

    }

@Test
public void combinePersons() throws ExecutionException, InterruptedException {
    CompletableFuture<Person> p1 = CompletableFuture.supplyAsync(() -> {
        return new Person("p1");
    });

    CompletableFuture<Person> p2 = CompletableFuture.supplyAsync(() -> {
        return new Person("p1");
    });

    CompletableFuture.allOf(p1, p2).thenAccept(it -> System.out.println(it));

}
公共类人物{
私有最终字符串名;
公众人物(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
}
@试验
public void combinePersons()引发ExecutionException、InterruptedException{
CompletableFuture p1=CompletableFuture.SupplySync(()->{
归还新人(“p1”);
});
CompletableFuture p2=CompletableFuture.SupplySync(()->{
归还新人(“p1”);
});
CompletableFuture.allOf(p1,p2)。然后接受(it->System.out.println(it));
}
该方法不公开传递给它的已完成的
CompletableFuture
实例的集合

返回一个新的
CompletableFuture
,当所有 给定的
CompletableFuture
s完成。如果有任何
CompletableFuture
s异常完成,然后返回
CompletableFuture
也会这样做,并保留一个
CompletionException
这是一个例外否则,结果(如果有) 给定的
CompletableFuture
s未反映在返回的
可完成的未来
,但可以通过检查它们来获得 单独地
。如果未提供
CompletableFuture
s,则返回
CompletableFuture
用值
null
完成

请注意,
allOf
还将异常完成的期货视为已完成。所以你不会总是有一个
一起工作。实际上,您可能有一个异常/可丢弃

如果您知道正在使用的
CompletableFuture
s的数量,请直接使用它们

CompletableFuture.allOf(p1, p2).thenAccept(it -> {
    Person person1 = p1.join();
    Person person2 = p2.join();
});
如果您不知道自己拥有多少(您正在使用一个数组或列表),只需捕获传递给
allOf

// make sure not to change the contents of this array
CompletableFuture<Person>[] persons = new CompletableFuture[] { p1, p2 };
CompletableFuture.allOf(persons).thenAccept(ignore -> {
   for (int i = 0; i < persons.length; i++ ) {
       Person current = persons[i].join();
   }
});

@用户874774哪种方法*?您的
combinePersons
方法?您需要对返回的
CompletableFuture
(或
get
)进行
join
,尽管这些方法正在阻止。@用户您必须使用提到的方法之一进行阻止,并重新处理传入的数组。@user您没有。您可以使用这些方法进行阻塞,以确保计算完成。然后使用数组从每个未来提取
Person
对象。@srborlongan哦,是的,我忘记了它的存在。@SotiriosDelimanolis我认为最好在
persons[I].join()中调用join()而不是get(),因为如果您在thenAccept块中,所有承诺都正确完成,因此任何承诺都会异常完成。如果不处理异常,代码会比从不缓存更简单。
@Test
public Person[] combinePersons() throws Exception {
    CompletableFuture<Person> p1 = CompletableFuture.supplyAsync(() -> {
        return new Person("p1");
    });

    CompletableFuture<Person> p2 = CompletableFuture.supplyAsync(() -> {
        return new Person("p1");
    });

    // make sure not to change the contents of this array
    CompletableFuture<Person>[] persons = new CompletableFuture[] { p1, p2 };
    // this will throw an exception if any of the futures complete exceptionally
    CompletableFuture.allOf(persons).join();

    return Arrays.stream(persons).map(CompletableFuture::join).toArray(Person[]::new);
}