java算法实践 将list中的元素按照属性分类成树状的map
来源:互联网 发布:音频发生器软件 编辑:程序博客网 时间:2024/06/05 03:37
java算法实践,同时也是一个有用的工具类。
例如:一个学生信息的list,学生的信息由班级、性别、学号等,将list按照班级、性别分类。
只需:
Map map = CollectionTools.classifyList(studentAllList,
"classId","sex");
例如:一个学生信息的list,学生的信息由班级、性别、学号等,将list按照班级、性别分类。
只需:
Map map = CollectionTools.classifyList(studentAllList,
"classId","sex");
这个工具运用反射可将list中的每一个学生按照classId和sex分类成一个树状的map。
package utils; import java.lang.reflect.InvocationTargetException;import java.util.ArrayList;import java.util.LinkedHashMap;import java.util.List;import java.util.Map; import org.apache.commons.beanutils.PropertyUtils;/** * * @author klguang * @version 0.1 */public class CollectionTools { /** * 运用PropertyUtils取得bean的值,并根据keyName归类 * * @param list * List beans * @param keyName * 需要归类的bean的属性名称 * @return LinkedHashMap<String, List>,有顺序的map<br> * map的key为需要归类的bean的属性名+"#"+对应的属性值:eg:"class#312"<br> * value为List<bean><br> * * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ public static LinkedHashMap<String, List> classify(List list, String keyName) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { LinkedHashMap<String, List> target = new LinkedHashMap(); for (Object obj : list) { // 取得bean需要归类的属性(keyName)的值,不做类型转换 Object oKeyValue = PropertyUtils.getProperty(obj, keyName); String keyValue = keyName + "#" + String.valueOf(oKeyValue); if (!target.containsKey(keyValue)) { // 如果map中没有归类key值,则添加key值和相应的list ArrayList keyList = new ArrayList(); keyList.add(obj); target.put(keyValue, keyList); } else { // 如果有归类key值,则在相应的list中添加这个bean ArrayList keyList = (ArrayList) target.get(keyValue); keyList.add(obj); } } return target; } /** * * 将归类的Map<String, List>按照 keyName归类,并用index控制递归。<br> * 因为直接调用没有意义,这个方法为private, * * @param mocl * map of classified list<br> * 也就是运用方法<br> * LinkedHashMap<String, List> classify(List list, String * keyName)<br> * 将list归类成的map<br> * * @param index * 用条件 index < keyNames.length控制递归 * * @param keyNames * 需要归类的bean的属性名称 * @return * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ private static LinkedHashMap<String, Map> classify(Map<String, List> mocl, int index, String... keyNames) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { // 单步理解:target是函数参数Map<String, List> mocl再次归类成的LinkedHashMap<String,Map> // 递归到最后这个是最终归类好的map LinkedHashMap<String, Map> target = new LinkedHashMap(); // 控制递归条件,起始的index应该总是1。 if (index < keyNames.length) { // swap用来保存参数index的值,这是最容易出错的一个地方 // 用它保证:在参数Map<String, List> mocl层面循环时用相同的index参数值。 int swap = index; for (Map.Entry<String, List> entry : mocl.entrySet()) { String mocl_key = entry.getKey(); List mocl_list = entry.getValue(); // 将List<bean>再次归类 LinkedHashMap<String, List> _mocl = classify(mocl_list, keyNames[index]); // 如果index达到了数组的最后一个,一定是List<bean>转map,递归结束 if (index == keyNames.length - 1) { target.put(mocl_key, _mocl); } else { // 将List<bean>转map得到的_mocl,再次归类 // _mocm 为map of classified map的简称 LinkedHashMap<String, Map> _mocm = classify(_mocl, ++index, keyNames); target.put(mocl_key, _mocm); } index = swap; } } return target; } /** * 将Map<String, List> map按照bean需要归类的属性名keyName归类 * * @param map * map of classified list<br> * list归类成的map * @param keyName * bean需要归类的属性名 * @return * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ public static LinkedHashMap<String, Map> classifyMap(Map<String, List> map, String keyName) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { LinkedHashMap<String, Map> target = new LinkedHashMap(); for (Map.Entry<String, List> entry : map.entrySet()) { List map_list = entry.getValue(); String map_key = entry.getKey(); LinkedHashMap<String, List> keyMap = classify(map_list, keyName); target.put(map_key, keyMap); } return target; } /** * 将List<bean> 按照指定的bean的属性进行归类,keyNames的先后顺序会影响归类结果。<br> * eg:一个学生列表,按照班级和性别归类<br> * Map map = CollectionUtils.classifyList(studentList, "classId","sex");<br> * * @param list * List beans * @param keyNames * 数组包含需要归类的bean的属性名称 * @return 归类的有顺序的树状map<br> * map的key为需要归类的bean的属性名+"#"+对应的属性值:eg:"class#312"<br> * map的值为List或者map * * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ public static LinkedHashMap classifyList(List list, String... keyNames) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { if (keyNames == null || keyNames.length == 0) return null; if (keyNames.length == 1) return classify(list, keyNames[0]); else return classify(classify(list, keyNames[0]), 1, keyNames); }}
package test; import java.lang.reflect.InvocationTargetException;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map; import utils.CollectionTools;import utils.JsonUtil; public class CollectionClassifytest { /** * @param args * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalAccessException */ public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { // TODO Auto-generated method stub List<Student> studentAllList = new ArrayList();// 所以班級的学生 studentAllList.add(new Student("1", "A", 1, "Ⅰ", "北", "1")); studentAllList.add(new Student("2", "C", 1, "Ⅱ", "上", "0")); studentAllList.add(new Student("3", "C", 1, "Ⅰ", "北", "1")); studentAllList.add(new Student("4", "B", 1, "Ⅰ", "广", "1")); studentAllList.add(new Student("5", "A", 1, "Ⅳ", "广", "1")); studentAllList.add(new Student("6", "C", 1, "Ⅳ", "上", "0")); studentAllList.add(new Student("7", "A", 1, "Ⅳ", "广", "0")); studentAllList.add(new Student("8", "B", 1, "Ⅰ", "广", "0")); studentAllList.add(new Student("8", "D", 1, "Ⅲ", "北", "0")); studentAllList.add(new Student("8", "D", 1, "Ⅲ", "广", "0")); studentAllList.add(new Student("8", "D", 1, "Ⅲ", "上", "0")); Map map = CollectionTools.classifyList(studentAllList, "classId","sex"); System.out.println(JsonUtil.toJSON(map)); //做对比 //System.out.println(JsonUtil.toJSON(classifyTest(studentAllList))); //Date begin=new Date(); //for (int i = 0; i < 1000000; i++) {// Map map = CollectionUtils.classifyList(studentAllList, "province", "academyId",// "classId", "team", "sex");// System.out.println(JsonUtil.toJSON(map)); //} //Date end=new Date(); //System.out.println(end.getTime()-begin.getTime()); } static Map classifyTest(List<Student> studentAllList) { // 步骤1 Map<String, List> map = new HashMap<String, List>(); Map<String, Object> mapLast = new HashMap<String, Object>(); // for(Student student : studentAllList){ for (Iterator it = studentAllList.iterator(); it.hasNext();) { Student student = (Student) it.next(); if (map.containsKey(student.getClassId())) { // 如果已经存在这个数组,就放在这里 List studentList = map.get(student.getClassId()); studentList.add(student); } else { List studentList = new ArrayList(); // 重新声明一个数组list studentList.add(student); map.put(student.getClassId(), studentList); } } // System.out.println(JsonUtil.toJSON(map)); // 步骤2 // 利用 处理1 步骤 分组完的数据 ,按性别 男/女 再次分组 for (Map.Entry<String, List> m : map.entrySet()) { // 按键值遍历 Map Map mapList = new HashMap(); // List studentSingle = m.getValue(); // 同一班级的学生,男女 List studentListMen = new ArrayList(); // 声明一个存放男生的 list List studentListWomen = new ArrayList(); // 声明一个存放女生的 list for (Iterator it = studentSingle.iterator(); it.hasNext();) {// 遍历 Student student = (Student) it.next(); if ("0".equals(student.getSex())) { // 男生 studentListMen.add(student); // 男生 } else { studentListWomen.add(student); // 女生 } } mapList.put("女", studentListWomen); mapList.put("男", studentListMen); mapLast.put(m.getKey(), mapList); } return mapLast; }}
package test; /** * @author klguang * */public class Student { private String studentId; // 学号 private String sex; // 性別 0 男 1 女 private int team; private String classId; private String academyId;//学院 private String province; public Student(String studentId, String classId, String sex) { super(); this.studentId = studentId; this.classId = classId; this.sex = sex; } public Student(String studentId, String classId,int team, String sex) { super(); this.studentId = studentId; this.classId = classId; this.team=team; this.sex = sex; } public Student(String studentId, String classId,int team, String academyId,String sex) { super(); this.studentId = studentId; this.classId = classId; this.team=team; this.sex = sex; this.academyId=academyId; } public Student(String studentId, String classId,int team, String academyId,String province,String sex) { super(); this.studentId = studentId; this.classId = classId; this.team=team; this.sex = sex; this.academyId=academyId; this.province=province; } public String getClassId() { return classId; } public void setClassId(String classId) { this.classId = classId; } public String getStudentId() { return studentId; } public void setStudentId(String studentId) { this.studentId = studentId; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getTeam() { return team; } public void setTeam(int team) { this.team = team; } public String getAcademyId() { return academyId; } public void setAcademyId(String academyId) { this.academyId = academyId; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } }
package utils; import java.util.Date; import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.serializer.SerializeConfig;import com.alibaba.fastjson.serializer.SerializerFeature;import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer; public class JsonUtil { private static SerializeConfig mapping = new SerializeConfig(); private static String dateFormat; static { dateFormat = "yyyy-MM-dd HH:mm:ss"; } public static String toJSON(Object jsonText) { return JSON.toJSONString(jsonText, SerializerFeature.WriteDateUseDateFormat); } public static String toJSON(String dateFormat, Object jsonText) { mapping.put(Date.class, new SimpleDateFormatSerializer(dateFormat)); return JSON.toJSONString(jsonText, mapping); } public static String toRealJSON(Object jsonText){ return JSON.toJSONString(jsonText,SerializerFeature.DisableCircularReferenceDetect); }}
{ "classId#A": { "sex#1": [ { "academyId": "Ⅰ", "classId": "A", "province": "北", "sex": "1", "studentId": "1", "team": 1 }, { "academyId": "Ⅳ", "classId": "A", "province": "广", "sex": "1", "studentId": "5", "team": 1 } ], "sex#0": [ { "academyId": "Ⅳ", "classId": "A", "province": "广", "sex": "0", "studentId": "7", "team": 1 } ] }, "classId#C": { "sex#0": [ { "academyId": "Ⅱ", "classId": "C", "province": "上", "sex": "0", "studentId": "2", "team": 1 }, { "academyId": "Ⅳ", "classId": "C", "province": "上", "sex": "0", "studentId": "6", "team": 1 } ], "sex#1": [ { "academyId": "Ⅰ", "classId": "C", "province": "北", "sex": "1", "studentId": "3", "team": 1 } ] }, "classId#B": { "sex#1": [ { "academyId": "Ⅰ", "classId": "B", "province": "广", "sex": "1", "studentId": "4", "team": 1 } ], "sex#0": [ { "academyId": "Ⅰ", "classId": "B", "province": "广", "sex": "0", "studentId": "8", "team": 1 } ] }, "classId#D": { "sex#0": [ { "academyId": "Ⅲ", "classId": "D", "province": "北", "sex": "0", "studentId": "8", "team": 1 }, { "academyId": "Ⅲ", "classId": "D", "province": "广", "sex": "0", "studentId": "8", "team": 1 }, { "academyId": "Ⅲ", "classId": "D", "province": "上", "sex": "0", "studentId": "8", "team": 1 } ] }}
0 0
- java算法实践 将list中的元素按照属性分类成树状的map
- 将list中的元素按照属性分类成树状的map
- Java中的List按照元素的属性进行排序
- 【java】将List中的实体按照某个字段进行分组的算法
- 【java】将List中的实体按照某个字段进行分组的算法
- List<Map<String,Object>>按照子元素中的时间排序
- java将对象列表中的某个属性转换成List或Map
- java list按照元素对象的指定多个字段属性进行排序
- java list按照元素对象的指定多个字段属性进行排序
- java list按照元素对象的指定多个字段属性进行排序
- java list按照元素对象的指定多个字段属性进行排序
- java list按照元素对象的指定多个字段属性进行排序
- 将java.util.list里的对象按照对象的某一属性排序
- 将List中的实体按照某个字段进行分组的算法
- 将List中的实体按照某个字段进行分组的算法
- CSS元素分类(按照样式属性)
- java集合list中的数据按照多个属性分组
- Java对List中的中文属性按照拼音排序
- iOS验证nib文件是否存在
- C++ Primer Chapter 11-2
- react native Android启动页面、修改图标、修改名字、修复启动白屏
- Android Activity或者Fragment 向Adapter实时传递参数
- 使用Maven创建Web应用程序项目(十)
- java算法实践 将list中的元素按照属性分类成树状的map
- 数学——CodeForces #410 div.2
- MTU问题,为何抓包到1514
- Android studio快捷键重写继承父类的抽象方法
- UML之了解
- C++ Primer Chapter 11-3
- Python语言程序设计
- 动态规划练习——怪盗基德的滑翔翼
- C++ Primer Chapter 12-1