树形结构代码来源:https://blog.youkuaiyun.com/Anenan/article/details/113029547
工具类代码来源:https://www.cnblogs.com/liangweiping/archive/2020/04/28/12792418.html
- pom.xml的依赖
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.2.4</version>
</dependency>
-
TreeNodeConfig的默认配置
-
测试用例
public static void main(String[] args) {
class City {
private Integer id;
private String cityName;
private Integer parentId;
private List<City> children;
//省略get,set
public City(Integer id, String cityName, Integer parentId) {
this.id = id;
this.cityName = cityName;
this.parentId = parentId;
}
}
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));
// 2.配置
TreeNodeConfig config = new TreeNodeConfig();
config.setIdKey(ColumnUtil.getName(City::getId));
//默认为id可以不设置
//config.setIdKey("id");
//默认为parentId可以不设置
//config.setParentIdKey("parentId");
//最大递归深度
//config.setDeep(2);
//默认为children不用设置
//config.setChildrenKey("children");
// 3.转树,Tree<>里面泛型为id的类型
List<Tree<Integer>> build = TreeUtil.build(cities, 0, config, (object, tree) -> {
// 也可以使用 tree.setId(object.getId());等一些默认值
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);
}
//如果不想全部字段可以按照下面的写法添加
/*tree.putExtra("id", object.getId());
tree.putExtra("parentId", object.getParentId());
tree.putExtra("cityName", object.getCityName());*/
});
System.out.println(JSON.toJSON(build));
}
- 推荐一个工具类给大家
/**
* 使Function获取序列化能力
*
* @author GideonYeung
* @date 2020/11/30 9:02
*/
@FunctionalInterface
public interface SerializableFunction<T, R> extends Function<T, R>, Serializable {
}
/**
* 获取某个实体类的字段名称
*
* @author GideonYeung
* @date 2020/11/30 9:03
*/
public class ColumnUtil {
public static <T> String getName(SerializableFunction<T, ?> fn) {
// 从function取出序列化方法
Method writeReplaceMethod;
try {
writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
// 从序列化方法取出序列化的lambda信息
boolean isAccessible = writeReplaceMethod.isAccessible();
writeReplaceMethod.setAccessible(true);
SerializedLambda serializedLambda;
try {
serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
writeReplaceMethod.setAccessible(isAccessible);
// 从lambda信息取出method、field、class等
String fieldName = serializedLambda.getImplMethodName().substring("get".length());
fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
return fieldName;
}
}