java算法实践 将list中的元素按照属性分类成树状的map

来源:互联网 发布:音频发生器软件 编辑:程序博客网 时间:2024/06/05 03:37
java算法实践,同时也是一个有用的工具类。
例如:一个学生信息的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
原创粉丝点击