map集合排序
这篇文章讲的不仅仅是map排序,比如把对象按某一属性排序,它都可以解决这些问题。
比如,有N个对象,每个对象有个属性就是成绩,成绩分:优秀,良好,合格。那我们如何按照成绩的好坏进行排序呢,下面请看代码。
1.people对象
package com.test; /*people对象其实很简单,就提供了三个属性*/ class People { private String Name; //姓名 private String Score; //成绩 private String id; //学号 public String getName() { return Name; } public void setName(String name) { Name = name; } public String getScore() { return Score; } public void setScore(String score) { Score = score; } public String getId() { return id; } public void setId(String id) { this.id = id; } public People(String name, String score, String id) { super(); Name = name; Score = score; this.id = id; } }
2.主要方法
package com.test; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; /** * Map进行多条件排序输出 * 成绩具有优秀,合格,不合格好吃属性。 * 入口Map * 首先按照优秀,合格,不合格排序 * 然后按照人名的标志Id排序 * 出口Map * * */ public class MainSort { /** * 准备参数,创建对象 * @return */ private static Map<String, People> getPeopleMap() { Map<String,People> PeopleMap = new TreeMap<>(); // 创建对象 People b = new People("小明" , "优秀", "b"); People a = new People("小红" , "合格", "a"); People c = new People("丁丁" , "合格", "c"); People d = new People("冬冬" , "良好", "d"); People e = new People("小黄" , "优秀", "e"); People f = new People("小李" , "良好", "f"); People g = new People("小钟" , "优秀", "g"); // 添加乱序key值,把对象放入map集合 PeopleMap.put("xniem", b); PeopleMap.put("akjd", a); PeopleMap.put("uioo", c); PeopleMap.put("qw84", d); PeopleMap.put("584sdf'", e); PeopleMap.put("4aisdf", f); PeopleMap.put("458jsf", g); return PeopleMap; } /** * 循环打印Map */ private static void show(Map<String, People> PeopleMap) { // 循环Map 这个打印肯定是无序的,也不是按放入的先后顺序 for (Map.Entry<String, People> PeopleOneMap : PeopleMap.entrySet()) { People People = PeopleOneMap.getValue(); System.out.println(People.getName() + " " + People.getScore()+ " " + People.getId() ); } } /* * 由于List能够直接使用Collections进行排序 * 但是Map不行。 * 这边所做的操作就是先将Map--》List * 然后对List进行排序 * 然后在讲List--》转换成LinkedHashMap * */ public static Map<String, People> sortMapByValue(Map<String, People> PeopleMap) { if (PeopleMap == null || PeopleMap.isEmpty()) { return null; } // LinkedHashMap是有序的、或者TreeMap都是有序的(这里只能用LinkedHashMap) Map<String, People> sortedMap = new LinkedHashMap<String, People>(); /* Set set=PeopleMap.entrySet(); PeopleMap.entrySet()返回的是一个set集合 * 再讲ArrayList(Collection<? extends E> c) 可以放collection,set集合是其子类,map不行哦 * 这步就是把map集合转为ArrayList集合 */ List<Map.Entry<String, People>> entryList = new ArrayList<Map.Entry<String, People>>(PeopleMap.entrySet()); //这步是关键,进过这步之后,entryList已经是个有序的ArrayList集合了 Collections.sort(entryList, new MapValueComparator()); //通过迭代器取出 Iterator<Map.Entry<String, People>> iter = entryList.iterator(); // Map.Entry<String, People>,就是包装了一个map节点,这个节点封装了key,value值,以及别的值(比如hashmap中哈希码和next指针) Map.Entry<String, People> tmpEntry = null; while (iter.hasNext()) { tmpEntry = iter.next(); sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue()); } return sortedMap; } /** * 主方法 * */ public static void main(String[] args) { // 获取Map Map<String,People> PeopleMap = getPeopleMap(); // 打印未排序的Map show(PeopleMap); System.out.println("-----------before-----------"); // 打印排序完了的Map show(MainSort.sortMapByValue(PeopleMap)); System.out.println("-----------after------------"); } }
3.Comparator方法
package com.test; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; class MapValueComparator implements Comparator<Map.Entry<String, People>> { @Override public int compare(Entry<String, People> o1, Entry<String, People> o2) { // 获取比较的两个对象 People People1 = o1.getValue(); People People2 = o2.getValue(); // 将成绩映射成具有比较关系的字符1、2、3 Map<String,Integer> tasteLev = new HashMap<>(); tasteLev.put("优秀", 1); tasteLev.put("良好", 2); tasteLev.put("合格", 3); int cr = 0; // 判断成绩 int a = tasteLev.get(People2.getScore())-tasteLev.get(People1.getScore()); if (a!=0) { cr = (a>0) ? -1 : 2; } else { /*其实上面就可以按成绩优秀,良好,合格排序了, *在做一步目的,就是在成绩相同的情况下,在按照学号进行排序 */ // 按照对应的Id排序 a = People2.getId().compareTo(People1.getId()); if (a!=0) { cr = (a>0)? -2 : 1; } } /* 注意上面对一个返回值对应的就是形成比较层次 * 上层 * --> 2 * --> -1 * 下层 * --> 1 * --> -2 */ return cr; } }
最后我们再来看后台输出