集合对象结合CompletableFuture异步批次查询聚合
import cn.hutool.core.collection.CollUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.function.Function;
import java.util.stream.Collectors;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class PartitionCallListAsyncUtil {
public static <T, V> List<V> partitionCallListAsync(List<T> dataList,
int size,
ExecutorService executorService,
Function<List<T>, List<V>> function) {
if (CollUtil.isEmpty(dataList)) {
return new ArrayList<>(0);
}
Preconditions.checkArgument(size > 0, "size must not be a minus");
List<CompletableFuture<List<V>>> completableFutures = Lists.partition(dataList, size)
.stream()
.map(eachList -> {
return null == executorService ? CompletableFuture.supplyAsync(() -> function.apply(eachList)) : CompletableFuture.supplyAsync(() -> function.apply(eachList), executorService);
})
.collect(Collectors.toList());
CompletableFuture<Void> allFinished = CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0]));
try {
allFinished.get();
} catch (Exception e) {
log.error("PartitionCallListAsyncUtil.partitionCallListAsync get error - {}", e);
throw new RuntimeException(e);
}
return completableFutures.stream()
.map(CompletableFuture::join)
.filter(CollUtil::isNotEmpty)
.reduce(new ArrayList<>(), ((list1, list2) -> {
return collectionAggregation(list1, list2);
}));
}
private static <V> List<V> collectionAggregation(List<V> ... sources){
List<V> result = new ArrayList<>();
for (List<V> source : sources){
if (CollUtil.isEmpty(source)){
continue;
}
result.addAll(source);
}
return result;
}
}