public class Test {
@Getter
@Setter
@ToString
public static class A {
private String id;
private String pId;
}
//重排序并进行展开
protected static <T, K> List<T> reorderAndOpen(List<T> oldList,
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends K> parentMapper,
BinaryOperator<T> mergeFunction) {
Map<K, T> tMapByk = oldList.stream().collect(Collectors.toMap(keyMapper, Function.identity(), mergeFunction));
List<T> treeList = new ArrayList<>();
Map<K, List<T>> childMap = new HashMap<>();
tMapByk.values().stream().forEach((t) -> {
K parentK = parentMapper.apply(t);
K own = keyMapper.apply(t);
if (!own.equals(parentK)) {
//自己的父类不能是自己
T parentT = tMapByk.get(parentK);
if (null == parentT) {
//如果父类是空的, 或者在该 Lis 中 没有知道, 那么, 就判定自己就是顶级父类
treeList.add(t);
} else {
List<T> childList = childMap.get(parentK);
if (null == childList) {
childList = new ArrayList<>();
}
childList.add(t);
childMap.put(parentK, childList);
}
}
});
List<T> openTreeList = new ArrayList<>();
openTree(treeList, childMap, keyMapper, openTreeList);
return openTreeList;
}
protected static <T, K> void openTree(List<T> treeList,
Map<K, List<T>> childMap,
Function<? super T, ? extends K> keyMapper,
List<T> openTreeList) {
if (treeList != null) {
for (T t : treeList) {
openTreeList.add(t);
System.out.println("父: " + JsonUtils.toJsonString(t));
List<T> childList = childMap.get(keyMapper.apply(t));
System.out.println("子: " + JsonUtils.toJsonString(childList));
openTree(childList, childMap, keyMapper, openTreeList);
}
}
}
public static void main(String[] args) {
A a = new A();
a.setId("0");
A a1 = new A();
a1.setId("1");
a1.setPId("0");
A a2 = new A();
a2.setId("2");
a2.setPId("0");
A a3 = new A();
a3.setId("3");
a3.setPId("1");
A a4 = new A();
a4.setId("4");
a4.setPId("1");
A a5 = new A();
a5.setId("5");
a5.setPId("1");
A a6 = new A();
a6.setId("6");
a6.setPId("2");
A a7 = new A();
a7.setId("7");
a7.setPId("0");
A a8 = new A();
a8.setId("8");
a8.setPId("6");
A a9 = new A();
a9.setId("9");
a9.setPId("4");
List<A> aList = new ArrayList<>();
aList.add(a);
aList.add(a1);
aList.add(a2);
aList.add(a3);
aList.add(a4);
aList.add(a5);
aList.add(a6);
aList.add(a7);
aList.add(a8);
aList.add(a9);
Collections.shuffle(aList);
List<A> reorder = reorder(aList, A::getId, A::getPId, (v1, v2) -> v1);
}
}
结果:
父: {"id":"0"}
子: [{"id":"1","pid":"0"},{"id":"2","pid":"0"},{"id":"7","pid":"0"}]
父: {"id":"1","pid":"0"}
子: [{"id":"3","pid":"1"},{"id":"4","pid":"1"},{"id":"5","pid":"1"}]
父: {"id":"3","pid":"1"}
子: null
父: {"id":"4","pid":"1"}
子: [{"id":"9","pid":"4"}]
父: {"id":"9","pid":"4"}
子: null
父: {"id":"5","pid":"1"}
子: null
父: {"id":"2","pid":"0"}
子: [{"id":"6","pid":"2"}]
父: {"id":"6","pid":"2"}
子: [{"id":"8","pid":"6"}]
父: {"id":"8","pid":"6"}
子: null
父: {"id":"7","pid":"0"}
子: null
/**
* 重排序(不展开)
*
* @param oldList 原本的List
* @param keyMapper 排序id
* @param parentMapper 排序父id
* @param mergeFunction id重复的处理方法
* @param <T> 对象
* @param <K> id
* @return 排序后的list
*/
public static <T extends AbstractReorder<T>, K> List<T> reorder(List<T> oldList,
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends K> parentMapper,
BinaryOperator<T> mergeFunction) {
Map<K, T> tMapByk = oldList.stream().collect(Collectors.toMap(keyMapper, Function.identity(), mergeFunction));
List<T> treeList = new ArrayList<>();
tMapByk.values().parallelStream().forEach((t) -> {
K parentK = parentMapper.apply(t);
K own = keyMapper.apply(t);
if (!own.equals(parentK)) {
//自己的父类不能是自己
T parentT = tMapByk.get(parentK);
if (null == parentT) {
//如果父类是空的, 或者在该 Lis 中 没有知道, 那么, 就判定自己就是顶级父类
treeList.add(t);
} else {
List<T> childList = parentT.getChildren();
if (null == childList) {
childList = new ArrayList<>();
}
childList.add(t);
parentT.setChildren(childList);
}
}
});
return treeList;
}
//因为无法知道需要将child塞到哪个字段上, 所以通过继承实现的方式去给child 赋值
public interface AbstractReorder<T> {
void setChildren(List<T> children);
List<T> getChildren();
}
@Getter
@Setter
@ToString
public class A implements AbstractReorder<A> {
private String id;
private String pId;
private List<A> child;
@Override
public void setChildren(List<AmisPage> children) {
this.child = children;
}
@Override
public List<AmisPage> getChildren() {
return child;
}
}