为CompletableFuture

时间:2017-06-06 12:55:19

标签: java generics java-8

我需要创建CompletableFuture个对象的通用数组,以便我可以将它传递给CompletableFuture.allOf方法以获得一个CompletableFuture来同步线程。但由于它是通用的我无法创建它。一个明显的解决方案是创建一个List,然后在其上调用toArray,但它效率低下。有没有更好的方法?这是我的代码:

// Current solution: 
List<CompletableFuture<List<ReportComparable>>> newReports = new ArrayList<>();

// Loop and add CompletableFuture objects to this list

// Collect all the retrieved objects here(Sync Threads).
    try {
        List<List<ReportComparable>> newReps = CompletableFuture.allOf((CompletableFuture<?>[]) newReports.toArray()).get();
    } catch (InterruptedException | ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

1 个答案:

答案 0 :(得分:4)

你的问题有几个错误的假设

  • 您不能(CompletableFuture<?>[]) newReports.toArray()。无参数toArray()方法将返回Object[],并且投射尝试将导致ClassCastException。只有接受现有数组的toArray(T[])方法才会返回相同类型的数组,这会使您回到方形零

  • CompletableFuture.allOf会返回CompletableFuture<Void>,因此您无法在其上调用get()并希望获得List<List<ReportComparable>>。您必须在完成后自行组装结果列表。

  • 当所有类型参数都是通配符时,创建泛型类的数组没有问题。所以

    CompletableFuture<?>[] array = new CompletableFuture<?>[100];
    

    的工作原理。

  • 如果您有任意数量的元素,将它们添加到List并在其上调用toArray,则效果不一定。另一种是手动处理数组和索引,与ArrayList的做法相同,但容易出错。 toArray的单一复制步骤很少与性能相关。

    另请注意,由于CompletableFuture.allOf返回CompletableFuture<Void>,您可能无论如何都需要List<CompletableFuture<List<ReportComparable>>>才能在完成后构建所需的List<List<ReportComparable>>

    另一方面,当您拥有固定数量的参数时,您可以直接调用 varargs 方法CompletableFuture.allOf而无需手动创建数组。

但是当您想要对CompletableFuture返回的allOf所做的只是立即呼叫get()时,“等待所有”操作无论如何都没有任何好处。

通过CompletableFutureget()查询单个join()实例并将结果添加到生成的List时,您会隐式获得相同的效果,无论如何您必须这样做完成后,由于CompletableFuture.allOf不适合你。