在我们实际的开发环境中,我们经常需要对Map集合按照键或者值进行排序,有时需要升序,有时又需要降序,为此笔者将自己平常使用的常见排序方法列出,以供大家参考,如有说的不对之处还望各位看官多多指教;
1、按键排序
首先来说按照键排序,一般来说,解决该问题的思路可以归纳为以下几种:
① 将Map集合转成TreeMap集合实现排序,可降序、升序,如下方法ordnarySortByTreeMap所示;
② 将Map集合转化成对应的Set集合,List集合,遍历List集合,最后将所有排序后的元素填充到一个新的Map集合中,例如以下方法ordnarySortByKey所示;
③ 将Map集合转化成Set集合。利用jdk8中的Stream进行排序,可利用Map.Entry中的排序器进行排序,具体操作如方法newSortByKey所示,该方法与其他的方法相比,最大的亮点就是优雅且可以支持多种排序功能;
/**
* @describtion: 按照键的普通排序
* @author: Sundz
* @date: 2020/1/2 22:15
* @param: [paramMap, isdesc] 入参集合 指定升序、降序
* @return: java.util.Map
*/
public static Map<String, Integer> ordnarySortByKey(Map<String, Integer> paramMap, boolean isdesc) {
Preconditions.checkNotNull(paramMap);
Set<Map.Entry<String, Integer>> sortedSet = paramMap.entrySet();
Preconditions.checkNotNull(sortedSet);
Map<String, Integer> resMap = new LinkedHashMap<>(paramMap.size());
List<Map.Entry<String, Integer>> sortedList = Lists.newArrayList(sortedSet);
//实现比较器
Comparator<Map.Entry<String, Integer>> comparator = new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> entry1, Map.Entry<String, Integer> entry2) {
//也可采用entry2比较entry1进行降序排序
return entry1.getKey().compareTo(entry2.getKey());
}
};
//降序 output:{dbc=9, cba=5, bca=16, abc=15}
if (isdesc) {
Collections.sort(sortedList, Collections.reverseOrder(comparator));
} else {
//升序 output:{abc=15, bca=16, cba=5, dbc=9}
Collections.sort(sortedList, comparator);
}
for (Map.Entry<String, Integer> entry : sortedList) {
String key = entry.getKey();
Integer value = entry.getValue();
if (StringUtils.isAnyBlank(key, String.valueOf(value))) {
continue;
}
resMap.put(key, value);
}
return resMap;
}
/**
* @describtion: 采用TreeMap的形式进行排序,默认升序
* @author: Sundz
* @date: 2020/1/2 22:25
* @param: [paramMap]
* @return: java.util.Map
*/
public static Map<String, Integer> ordnarySortByTreeMap(Map<String, Integer> paramMap) {
Preconditions.checkNotNull(paramMap);
//此处需要将非TreeMap转化成TreeMap,可采用for循环遍历的方式,然后put,但是今天我们玩点新花样
//output:{abc=15, bca=16, cba=5, dbc=9}
return paramMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> x, TreeMap::new));
}
/**
* @describtion: 优雅实现排序,jdk8的新语法,最后的转化集合必须是LinkedHashMap,这样才能保持插入的顺序
* @author: Sundz
* @date: 2020/1/2 22:28
* @param: [paramMap, isdesc]
* @return: java.util.Map
*/
public static Map<String, Integer> newSortByKey(Map<String, Integer> paramMap, boolean isdesc) {
Preconditions.checkNotNull(paramMap);
if (isdesc) {
// output:{dbc=9, cba=5, bca=16, abc=15}
//jdk8 中Map.Entry接口支持多种排序,可按键,按值、颠倒及多个比较器组合等形式进行排序
return paramMap.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByKey().reversed()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> x, LinkedHashMap::new));
} else {
//output:{abc=15, bca=16, cba=5, dbc=9}
return paramMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> x, LinkedHashMap::new));
}
}
2、按值排序
按照Map集合的值进行排序,也是我们经常遇到的场景,为此笔者也做了一个简单的总结,按照值进行排序可以从几个角度进行思考:
① 可采用将其转化成对应的Set集合进行排序,然后将添加至对应的Map集合,从而实现排序,如方法ordnarySortByValue所示;
② 将集合转化成Set集合,采用流的形式进行排序,最后收集成Map集合;
/**
* @describtion: 按照值进行排序
* @author: Sundz
* @date: 2020/1/3 21:29
* @param: [paramMap, isDesc] //{bca=16, cba=5, abc=15, dbc=9}
* @return: java.util.Map
*/
public static Map<String, Integer> ordnarySortByValue(Map<String, Integer> paramMap, boolean isDesc) {
Objects.requireNonNull(paramMap);
Comparator<Map.Entry<String, Integer>> comparator = Comparator.comparing(Map.Entry::getValue);
Set<Map.Entry<String, Integer>> sortedSet = null;
if (isDesc) {
//output:{bca=16, abc=15, dbc=9, cba=5}
sortedSet = FluentIterable.from(paramMap.entrySet()).toSortedSet(comparator);
} else {
//output:{cba=5, dbc=9, abc=15, bca=16}
sortedSet = FluentIterable.from(paramMap.entrySet()).toSortedSet(Collections.reverseOrder(comparator));
}
Map<String, Integer> resMap = new LinkedHashMap<>(paramMap.size());
for (Map.Entry<String, Integer> entry : sortedSet) {
String key = entry.getKey();
Integer value = entry.getValue();
if (!StringUtils.isAnyBlank(key, String.valueOf(value))) {
resMap.put(key, value);
}
}
return resMap;
}
/**
* @describtion: 采用Stream的形式进行排序且转化成Map集合
* @author: Sundz
* @date: 2020/1/3 21:37
* @param: [paramMap, isDesc]
* @return: java.util.Map
*/
public static Map<String, Integer> newSortedByValue(Map<String, Integer> paramMap, boolean isDesc) {
Objects.requireNonNull(paramMap);
if (isDesc) {
return paramMap.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue().reversed()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> x, LinkedHashMap::new));
} else {
return paramMap.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> x, LinkedHashMap::new));
}
}
赠人玫瑰,手有余香,请留下您的宝贵建议或者赞吧!