我需要创建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();
}
答案 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()
时,“等待所有”操作无论如何都没有任何好处。
通过CompletableFuture
或get()
查询单个join()
实例并将结果添加到生成的List
时,您会隐式获得相同的效果,无论如何您必须这样做完成后,由于CompletableFuture.allOf
不适合你。