经常碰到一个功能,是将一个list的数据转换成数据结构,以前每次都是用递归方式进行组装,后来在网上查找了下,看到利用java反射机制封装的一个公用方法,觉得不错,但是网上能搜索到的发现大部分都是利用实体类的属性,调用clazz.getDeclaredField()方法来实现的,但这样有一定的局限性,该方法只能获取到自身的属性,从父类继承的private属性获取不到,于是把代码修改了下,利用反射方法来实现,代码如下
/**
* 将list组装成tree
* @param tree 传入的list
* @param topParentId 最顶层的父ID
* @return
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
public static List toTree(List tree,String topParentId) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
if (tree !=null){
List t_list = new ArrayList();
Map map = new HashMap();
for (Object o : tree){
Class clazz = o.getClass();
Method method = clazz.getMethod("getId");
String id = method.invoke(o).toString();
map.put(id,o);
}
for (Object o : map.keySet()){
String id = o.toString();
Object obj = map.get(id);
Class clazz = obj.getClass();
Method method = clazz.getMethod("getParentId");
String parentId = method.invoke(obj).toString();
if (StringUtils.pathEquals(parentId,topParentId)){
//顶层
t_list.add(obj);
}else {
//当不是顶层时,获取其父级
Object object = map.get(parentId);
Class parentClazz = object.getClass();
Method getChildren = parentClazz.getMethod("getChildren");
//获取其父级的子级,及自己的兄弟(平级)
List list =(List) getChildren.invoke(object);
if (CollectionUtils.isEmpty(list)){
list = new ArrayList();
}
list.add(obj);
Method setChildren = parentClazz.getMethod("setChildren",List.class);
setChildren.invoke(object,list);
}
}
return t_list;
}
return null;
}