import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @Description: 树构造器
* @author: Mr.xulong
* @date: 2023年08月01日 16:04
*/
public class TreePlusBuilder {
/**
* 使用多线程组装树结构
*
* @param allNodes 列表
* @param idExtractor id
* @param parentIdExtractor 父级id
* @param childrenSetter 子集
* @param rootParentId 根节点的父级id
* @param <T>
* @return
* @throws InterruptedException
* @throws ExecutionException
*/
public static <T> List<T> assembleTreeMultithreaded(List<T> allNodes, Function<T, Long> idExtractor, Function<T, Long> parentIdExtractor, BiConsumer<T, List<T>> childrenSetter, Long rootParentId, boolean includingParent) {
int size = allNodes.size();
double divisionResult = (double) size / 1000;
double ceilResult = Math.ceil(divisionResult);
int bagNum = (int) ceilResult;
try {
// 创建线程池
ExecutorService executor = new ThreadPoolExecutor(10, 20, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
// 将列表拆分为多个子列表
List<List<T>> nodeSublists = splitList(allNodes, bagNum, idExtractor);
// 创建Callable任务列表
List<Callable<List<T>>> callableTasks = new ArrayList<>();
for (List<T> sublist : nodeSublists) {
List<Long> nodeIds = sublist.stream().map(o -> idExtractor.apply(o)).collect(Collectors.toList());
callableTasks.add(new TreeCallableBuilder(allNodes, nodeIds, idExtractor, parentIdExtractor, childrenSetter, rootParentId));
}
// 执行任务并收集结果
List<Future<List<T>>> futures = executor.invokeAll(callableTasks);
// 关闭线程池
executor.shutdown();
// 合并子树为完整的树
if(null == rootParentId){
return allNodes.stream().filter(m -> null == parentIdExtractor.apply(m)).collect(Collectors.toList());
}
if(includingParent){
return allNodes.stream().filter(m -> idExtractor.apply(m).equals(rootParentId)).collect(Collectors.toList());
}else {
return allNodes.stream().filter(m -> parentIdExtractor.apply(m).equals(rootParentId)).collect(Collectors.toList());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
throw new CustomException(ex.getMessage());
}
}
/**
* 将列表拆分为指定数量的子列表
*
* @param <T>
* @param list
* @param numSublists
* @return
*/
private static <T> List<List<T>> splitList(List<T> list, int numSublists, Function<T, Long> idExtractor) {
List<List<T>> sublists = new ArrayList<>();
int size = list.size();
int batchSize = (size + numSublists - 1) / numSublists;
int fromIndex = 0;
int toIndex = batchSize;
for (int i = 0; i < numSublists; i++) {
if (fromIndex < size) {
sublists.add(list.subList(fromIndex, Math.min(toIndex, size)));
}
fromIndex = toIndex;
toIndex += batchSize;
}
return sublists;
}
/**
* Callable任务用于构建树结构
*
* @param <T>
*/
private static class TreeCallableBuilder<T> implements Callable<Void> {
private List<T> allNodes;
private List<Long> nodes;
private Function<T, Long> idExtractor;
private Function<T, Long> parentIdExtractor;
private BiConsumer<T, List<T>> childrenSetter;
private Long rootParentId = 0L;
public TreeCallableBuilder(List<T> allNodes, List<Long> nodes, Function<T, Long> idExtractor,
Function<T, Long> parentIdExtractor, BiConsumer<T, List<T>> childrenSetter, Long rootParentId) {
this.allNodes = allNodes;
this.nodes = nodes;
this.idExtractor = idExtractor;
this.parentIdExtractor = parentIdExtractor;
this.childrenSetter = childrenSetter;
this.rootParentId = rootParentId;
}
@Override
public Void call() {
for (Long nodeId : nodes) {
Optional<T> nodeOptional = allNodes.stream().filter(m -> idExtractor.apply(m).equals(nodeId)).findFirst();
if (nodeOptional.isPresent()) {
T node = nodeOptional.get();
List<T> childs = allNodes.stream().filter(m -> parentIdExtractor.apply(m) != null && parentIdExtractor.apply(m).equals(nodeId)).collect(Collectors.toList());
childrenSetter.accept(node, childs);
}
}
return null;
}
}
public static void main(String[] args) {
List<SelectTreeModel> results = new ArrayList<>();
SelectTreeModel m1 = new SelectTreeModel();
m1.setId(1L);
m1.setParentId(null);
m1.setLabel("一级");
results.add(m1);
SelectTreeModel m2 = new SelectTreeModel();
m2.setId(2L);
m2.setParentId(1L);
m2.setLabel("二级");
results.add(m2);
SelectTreeModel m3 = new SelectTreeModel();
m3.setId(3L);
m3.setParentId(2L);
m3.setLabel("三级");
results.add(m3);
SelectTreeModel m4 = new SelectTreeModel();
m4.setId(4L);
m4.setParentId(3L);
m4.setLabel("四级");
results.add(m4);
SelectTreeModel m5 = new SelectTreeModel();
m5.setId(5L);
m5.setParentId(4L);
m5.setLabel("五级");
results.add(m5);
SelectTreeModel m6 = new SelectTreeModel();
m6.setId(6L);
m6.setParentId(5L);
m6.setLabel("六级");
results.add(m6);
List<SelectTreeModel> ret = TreePlusBuilder.assembleTreeMultithreaded(results, SelectTreeModel::getId, SelectTreeModel::getParentId, SelectTreeModel::setChildren, null,false);
System.out.println(ret);
}
}
Java使用多线程进行组装树
最新推荐文章于 2024-07-22 14:15:06 发布