树型结构的通用实现方法
- 树型结构的通用实现demo 下载0积分
- 实现思路 -> 将每个对象以其parentId作为key,填充到parentMap中,然后寻找顶级节点,然后迭代每一个顶级节点,以每一个顶级节点的id作为key值从parentMap中获取下级节点
- Node 接口 如果需要使用此通用实现方法 需要实现Node接口
public interface Node {
String getId();
void setId(String id);
String getParentId();
void setParentId(String parentId);
}
- 具体的实现代码
public interface TreeImplComponent<T extends Node> {
default void fillParentMap(List<T> list, Map<String, Map<String, T>> parentMap) {
this.fillParentMap(list, parentMap, t -> {
});
}
default void fillParentMap(List<T> list, Map<String, Map<String, T>> parentMap, Consumer<T> consumer) {
list.forEach(t -> {
String parentId = t.getParentId();
this.putData(parentMap, parentId, t);
consumer.accept(t);
});
}
void fillBasicData(List<T> list, Map<String, Map<String, T>> parentMap, List<T> topNodes);
List<T> sort(List<T> list);
T copyProperties(T ori);
default List<T> buildTree(List<T> list, BiConsumer<T, List<T>> consumer) {
if (CollectionUtils.isNotEmpty(list)) {
if (list.size() > 1) {
Map<String, Map<String, T>> parentMap = this.synchronizedMap();
List<T> topNodes = this.synchronizedList(100);
this.fillBasicData(list, parentMap, topNodes);
return this.buildTree(topNodes, parentMap, consumer);
} else {
return list;
}
} else {
return this.emptyList();
}
}
default List<T> buildTree(List<T> topNodes, Map<String, Map<String, T>> parentMap, BiConsumer<T, List<T>> consumer) {
List<T> nodes = this.synchronizedList(100);
this.sort(topNodes).forEach(t -> {
if (t != null) {
T node = this.copyProperties(t);
String id = t.getId();
Map<String, T> map = parentMap.get(id);
List<T> children;
if (map != null) {
children = this.buildTree(this.synchronizedList(map.values()), parentMap, consumer);
} else {
children = this.emptyList();
}
consumer.accept(node, children);
nodes.add(node);
}
});
return nodes;
}
default List<T> layoutTree(List<T> nodes, Function<T, List<T>> function) {
List<T> list = this.synchronizedList(1000);
this.layoutTree(nodes, list, function);
return list;
}
default void layoutTree(List<T> nodes, List<T> results, Function<T, List<T>> function) {
nodes.forEach(node -> {
T dest = this.copyProperties(node);
List<T> children = function.apply(dest);
results.add(dest);
if (CollectionUtils.isNotEmpty(children)) {
this.layoutTree(children, results, function);
}
});
}
default <K, V> Map<K, V> synchronizedMap() {
return Collections.synchronizedMap(new LinkedHashMap<>());
}
default <K> List<K> synchronizedList(int initialCapacity) {
return this.synchronizedList(new ArrayList<>(initialCapacity));
}
default <K> List<K> synchronizedList(Collection<K> coll) {
return Collections.synchronizedList(new ArrayList<>(coll));
}
default <K> List<K> emptyList() {
return Collections.emptyList();
}
default <K, V extends Node> void putData(Map<K, Map<String, V>> dataMap, K key, V v) {
Map<String, V> map = dataMap.get(key);
Map<String, V> tempMap = this.synchronizedMap();
if (map != null) {
map.forEach(tempMap::put);
}
tempMap.put(v.getId(), v);
dataMap.put(key, tempMap);
}
}
- 附带的demo项目 使用idea编辑的