将List中的元素按照属性分类成树状的map

例如:一个学生信息的list,学生的信息由班级、性别、学号等,将list按照班级、性别分类。
只需:
     Map map = CollectionTools.classifyList(studentAllList, "classId","sex");
这个工具运用反射可将list中的每一个学生按照classId和sex分类成一个树状的map。

  1 import java.lang.reflect.InvocationTargetException;
  2 import java.util.ArrayList;
  3 import java.util.LinkedHashMap;
  4 import java.util.List;
  5 import java.util.Map;
  6 
  7 import org.apache.commons.beanutils.PropertyUtils;
  8 
  9 
 10 public class CollectionUtils {
 11 
 12     /**
 13      * 运用PropertyUtils取得bean的值,并根据keyName归类
 14      *
 15      * @param list    List beans
 16      * @param keyName 需要归类的bean的属性名称
 17      * @return LinkedHashMap<String , List>,有顺序的map<br>
 18      * map的key为需要归类的bean的属性名+"#"+对应的属性值:eg:"class#312"<br>
 19      * value为List<bean><br>
 20      * @throws IllegalAccessException
 21      * @throws InvocationTargetException
 22      * @throws NoSuchMethodException
 23      */
 24 
 25     public static LinkedHashMap<String, List> classify(List list, String keyName)
 26             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
 27         LinkedHashMap<String, List> target = new LinkedHashMap();
 28         for (Object obj : list) {
 29             // 取得bean需要归类的属性(keyName)的值,不做类型转换
 30             Object oKeyValue = PropertyUtils.getProperty(obj, keyName);
 31             String keyValue = keyName + "#" + String.valueOf(oKeyValue);
 32             if (!target.containsKey(keyValue)) {
 33                 // 如果map中没有归类key值,则添加key值和相应的list
 34                 ArrayList keyList = new ArrayList();
 35                 keyList.add(obj);
 36                 target.put(keyValue, keyList);
 37             } else {
 38                 // 如果有归类key值,则在相应的list中添加这个bean
 39                 ArrayList keyList = (ArrayList) target.get(keyValue);
 40                 keyList.add(obj);
 41             }
 42         }
 43         return target;
 44     }
 45 
 46     /**
 47      * 将归类的Map<String, List>按照 keyName归类,并用index控制递归。<br>
 48      * 因为直接调用没有意义,这个方法为private,
 49      *
 50      * @param mocl     map of classified list<br>
 51      *                 也就是运用方法<br>
 52      *                 LinkedHashMap<String, List> classify(List list, String
 53      *                 keyName)<br>
 54      *                 将list归类成的map<br>
 55      * @param index    用条件 index < keyNames.length控制递归
 56      * @param keyNames 需要归类的bean的属性名称
 57      * @return
 58      * @throws IllegalAccessException
 59      * @throws InvocationTargetException
 60      * @throws NoSuchMethodException
 61      */
 62 
 63     private static LinkedHashMap<String, Map> classify(Map<String, List> mocl, int index,
 64                                                        String... keyNames) throws IllegalAccessException, InvocationTargetException,
 65             NoSuchMethodException {
 66         // 单步理解:target是函数参数Map<String, List> mocl再次归类成的LinkedHashMap<String,Map>
 67         // 递归到最后这个是最终归类好的map
 68         LinkedHashMap<String, Map> target = new LinkedHashMap();
 69         // 控制递归条件,起始的index应该总是1。
 70         if (index < keyNames.length) {
 71             // swap用来保存参数index的值,这是最容易出错的一个地方
 72             // 用它保证:在参数Map<String, List> mocl层面循环时用相同的index参数值。
 73             int swap = index;
 74             for (Map.Entry<String, List> entry : mocl.entrySet()) {
 75                 String mocl_key = entry.getKey();
 76                 List mocl_list = entry.getValue();
 77                 // 将List<bean>再次归类
 78                 LinkedHashMap<String, List> _mocl = classify(mocl_list, keyNames[index]);
 79                 // 如果index达到了数组的最后一个,一定是List<bean>转map,递归结束
 80                 if (index == keyNames.length - 1) {
 81                     target.put(mocl_key, _mocl);
 82                 } else {
 83                     // 将List<bean>转map得到的_mocl,再次归类
 84                     // _mocm 为map of classified map的简称
 85                     LinkedHashMap<String, Map> _mocm = classify(_mocl, ++index, keyNames);
 86                     target.put(mocl_key, _mocm);
 87                 }
 88                 index = swap;
 89             }
 90         }
 91         return target;
 92     }
 93 
 94     /**
 95      * 将Map<String, List> map按照bean需要归类的属性名keyName归类
 96      *
 97      * @param map     map of classified list<br>
 98      *                list归类成的map
 99      * @param keyName bean需要归类的属性名
100      * @return
101      * @throws IllegalAccessException
102      * @throws InvocationTargetException
103      * @throws NoSuchMethodException
104      */
105 
106     public static LinkedHashMap<String, Map> classifyMap(Map<String, List> map, String keyName)
107             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
108         LinkedHashMap<String, Map> target = new LinkedHashMap();
109         for (Map.Entry<String, List> entry : map.entrySet()) {
110             List map_list = entry.getValue();
111             String map_key = entry.getKey();
112             LinkedHashMap<String, List> keyMap = classify(map_list, keyName);
113             target.put(map_key, keyMap);
114         }
115         return target;
116     }
117 
118     /**
119      * 将List<bean> 按照指定的bean的属性进行归类,keyNames的先后顺序会影响归类结果。<br>
120      * eg:一个学生列表,按照班级和性别归类<br>
121      * Map map = CollectionUtils.classifyList(studentList, "classId","sex");<br>
122      *
123      * @param list     List beans
124      * @param keyNames 数组包含需要归类的bean的属性名称
125      * @return 归类的有顺序的树状map<br>
126      * map的key为需要归类的bean的属性名+"#"+对应的属性值:eg:"class#312"<br>
127      * map的值为List或者map
128      * @throws IllegalAccessException
129      * @throws InvocationTargetException
130      * @throws NoSuchMethodException
131      */
132     public static LinkedHashMap classifyList(List list, String... keyNames)
133             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
134         if (keyNames == null || keyNames.length == 0)
135             return null;
136         if (keyNames.length == 1)
137             return classify(list, keyNames[0]);
138         else
139             return classify(classify(list, keyNames[0]), 1, keyNames);
140     }
141 }

 

转载于:https://www.cnblogs.com/llawliet0001/p/9835543.html

你可以使用递归来将一个具有父子关系的列表转换为树形结构。以下是一个示例代码,演示了如何将一个 `List<Map<String, Object>>` 转换为树形结构: ```java import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MapListToTree { public static void main(String[] args) { List<Map<String, Object>> mapList = new ArrayList<>(); Map<String, Object> map1 = new HashMap<>(); map1.put("id", 1); map1.put("name", "Node 1"); map1.put("parentId", null); mapList.add(map1); Map<String, Object> map2 = new HashMap<>(); map2.put("id", 2); map2.put("name", "Node 2"); map2.put("parentId", 1); mapList.add(map2); Map<String, Object> map3 = new HashMap<>(); map3.put("id", 3); map3.put("name", "Node 3"); map3.put("parentId", null); mapList.add(map3); List<Map<String, Object>> tree = buildTree(mapList, null); System.out.println(tree); } private static List<Map<String, Object>> buildTree(List<Map<String, Object>> nodes, Object parentId) { List<Map<String, Object>> tree = new ArrayList<>(); for (Map<String, Object> node : nodes) { Object nodeParentId = node.get("parentId"); if ((nodeParentId == null && parentId == null) || (nodeParentId != null && nodeParentId.equals(parentId))) { List<Map<String, Object>> children = buildTree(nodes, node.get("id")); node.put("children", children); tree.add(node); } } return tree; } } ``` 这段代码首先创建了一个 `mapList`,其包含了一些具有父子关系的节点。然后,通过调用 `buildTree` 方法,将 `mapList` 转换为树形结构。最后,输出转换后的树形结构。 请根据你的实际情况修改节点的属性和父子关系的表示方式。这只是一个示例,你可以根据需求进行适当的修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值