TreeUtil
import java.util.*;
import java.util.function.ToIntFunction;
public final class TreeUtil {
private TreeUtil() {
}
public static <T extends TreeModel<T>> List<T> listToTree(List<T> list) {
return listToTree(list, null);
}
public static <T extends TreeModel<T>> List<T> listToTree(List<T> list, Comparator<T> compare) {
Map<String, List<T>> groupMap = new HashMap<>();
Map<String, T> idMap = new HashMap<>();
List<T> result = new ArrayList<>();
for (T t : list) {
idMap.put(t.getId(), t);
List<T> children = groupMap.computeIfAbsent(t.getParentId(), k -> new ArrayList<>());
children.add(t);
}
if (compare != null) {
for (HashMap.Entry<String, List<T>> entry : groupMap.entrySet()) {
String key = entry.getKey();
List<T> value = entry.getValue();
value.sort(compare);
matchChildren(key, value, idMap, result);
}
result.sort(compare);
}
else {
for (HashMap.Entry<String, List<T>> entry : groupMap.entrySet()) {
String key = entry.getKey();
List<T> value = entry.getValue();
matchChildren(key, value, idMap, result);
}
}
return result;
}
private static <T extends TreeModel<T>> void matchChildren(String key, List<T> value, Map<String, T> idMap, List<T> result) {
T t = idMap.get(key);
if (t != null) {
t.setChildren(value);
} else {
result.addAll(value);
}
}
}
TreeModel
public interface TreeModel<T> {
String getId();
String getParentId();
T setChildren(List<T> children);
}
Menu 菜单类
@Data
@Accessors(chain = true)
public class Menu implements TreeModel<Menu> {
private String id;
private String parentId;
private String url;
private Integer sort;
private List<Menu> children;
public Menu() {
}
public Menu(String id, String parentId, String url, Integer sort) {
this.id = id;
this.parentId = parentId;
this.url = url;
this.sort = sort;
}
}
测试
public class MenuDemo {
public static void main(String[] args) {
ArrayList<Menu> list = new ArrayList<>();
list.add(new Menu("1", "0", "/abc", 1));
list.add(new Menu("2", "1", "/aaa", 5));
list.add(new Menu("3", "1", "/bbb", 2));
list.add(new Menu("4", "2", "/ccc", 1));
list.add(new Menu("5", "0", "/ddd", 15));
list.add(new Menu("6", "5", "/eee", 14));
list.add(new Menu("7", "6", "/fff", 10));
list.add(new Menu("8", "6", "/ggg", 15));
List<Menu> menus = TreeUtil.listToTree(list);
System.out.println(JSON.toJSONString(menus));
List<Menu> menusSort = TreeUtil.listToTree(list, Comparator.comparing(Menu::getSort));
System.out.println(JSON.toJSONString(menusSort));
}
}
Hutool-TreeUtil
City 类
@Data
public class City {
private Integer id;
private String cityName;
private Integer parentId;
private List<City> children;
public City(Integer id, String cityName, Integer parentId) {
this.id = id;
this.cityName = cityName;
this.parentId = parentId;
}
}
测试代码
public class CityDemo {
public static void main(String[] args) {
List<City> cities = CollUtil.newArrayList();
cities.add(new City(1, "广东省", 0));
cities.add(new City(2, "广州市", 1));
cities.add(new City(3, "南沙区", 2));
cities.add(new City(4, "万顷沙镇", 3));
cities.add(new City(5, "黄阁镇", 3));
cities.add(new City(6, "湖南省", 0));
cities.add(new City(7, "长沙市", 6));
cities.add(new City(8, "芙蓉区", 7));
TreeNodeConfig config = new TreeNodeConfig();
config.setIdKey("id");
config.setParentIdKey("parentId");
config.setDeep(3);
config.setChildrenKey("children");
List<Tree<Integer>> build = TreeUtil.build(cities, 0, config, (object, tree) -> {
Field[] fields = ReflectUtil.getFieldsDirectly(object.getClass(), true);
for (Field field : fields) {
String fieldName = field.getName();
Object fieldValue = ReflectUtil.getFieldValue(object, field);
tree.putExtra(fieldName, fieldValue);
}
});
System.out.println(JSON.toJSON(build));
}
}