码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-10-23 11:53:59      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:port   java   key   hash   .property   vat   nta   get   添加   

例如:一个学生信息的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 }

 

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

标签:port   java   key   hash   .property   vat   nta   get   添加   

原文地址:https://www.cnblogs.com/llawliet0001/p/9835543.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!