浅谈Java之Map 按值排序 (Map sort by value)
Map是键值对的集合,又叫作字典或关联数组等,是最常见的数据结构之一。在java如何让一个map按value排序呢? 看似简单,但却不容易!
比如,Map中key是String类型,表示一个单词,而value是int型,表示该单词出现的次数,现在我们想要按照单词出现的次数来排序:
Map map = new TreeMap(); map.put("me", 1000); map.put("and", 4000); map.put("you", 3000); map.put("food", 10000); map.put("hungry", 5000); map.put("later", 6000);
按值排序的结果应该是:
key value me 1000 you 3000 and 4000 hungry 5000 later 6000 food 10000
首先,不能采用SortedMap结构,因为SortedMap是按键排序的Map,而不是按值排序的Map,我们要的是按值排序的Map。
Couldn't you do this with a SortedMap?
No, because the map are being sorted by its keys.
方法一:
如下Java代码:
import java.util.Iterator; import java.util.Set; import java.util.TreeSet; public class Main { public static void main(String[] args) { Set set = new TreeSet(); set.add(new Pair("me", "1000")); set.add(new Pair("and", "4000")); set.add(new Pair("you", "3000")); set.add(new Pair("food", "10000")); set.add(new Pair("hungry", "5000")); set.add(new Pair("later", "6000")); set.add(new Pair("myself", "1000")); for (Iterator i = set.iterator(); i.hasNext();) System.out.println(i.next()); } } class Pair implements Comparable { private final String name; private final int number; public Pair(String name, int number) { this.name = name; this.number = number; } public Pair(String name, String number) throws NumberFormatException { this.name = name; this.number = Integer.parseInt(number); } public int compareTo(Object o) { if (o instanceof Pair) { int cmp = Double.compare(number, ((Pair) o).number); if (cmp != 0) { return cmp; } return name.compareTo(((Pair) o).name); } throw new ClassCastException("Cannot compare Pair with " + o.getClass().getName()); } public String toString() { return name + ' ' + number; } }
类似的C++代码:
typedef pair<string, int> PAIR; int cmp(const PAIR& x, const PAIR& y) { return x.second > y.second; } map<string,int> m; vector<PAIR> vec; for (map<wstring,int>::iterator curr = m.begin(); curr != m.end(); ++curr) { vec.push_back(make_pair(curr->first, curr->second)); } sort(vec.begin(), vec.end(), cmp);
上面方法的实质意义是:将Map结构中的键值对(Map.Entry)封装成一个自定义的类(结构),或者直接用Map.Entry类。自定义类知道自己应该如何排序,也就是按值排序,具体为自己实现Comparable接口或构造一个Comparator对象,然后不用Map结构而采用有序集合(SortedSet, TreeSet是SortedSet的一种实现),这样就实现了Map中sort by value要达到的目的。就是说,不用Map,而是把Map.Entry当作一个对象,这样问题变为实现一个该对象的有序集合或对该对象的集合做排序。既可以用SortedSet,这样插入完成后自然就是有序的了,又或者用一个List或数组,然后再对其做排序(Collections.sort() or Arrays.sort())。
Encapsulate the information in its own class. Either implement
Comparable and write rules for the natural ordering or write a
Comparator based on your criteria. Store the information in a sorted
collection, or use the Collections.sort() method.
方法二:
You can also use the following code to sort by value:
public static Map sortByValue(Map map) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } }); Map result = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); result.put(entry.getKey(), entry.getValue()); } return result; } public static Map sortByValue(Map map, final boolean reverse) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { if (reverse) { return -((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } }); Map result = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); result.put(entry.getKey(), entry.getValue()); } return result; } Map map = new HashMap(); map.put("a", 4); map.put("b", 1); map.put("c", 3); map.put("d", 2); Map sorted = sortByValue(map); System.out.println(sorted); // output : {b=1, d=2, c=3, a=4} 或者还可以这样: Map map = new HashMap(); map.put("a", 4); map.put("b", 1); map.put("c", 3); map.put("d", 2); Set<Map.Entry<String, Integer>> treeSet = new TreeSet<Map.Entry<String, Integer>>( new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { Integer d1 = o1.getValue(); Integer d2 = o2.getValue(); int r = d2.compareTo(d1); if (r != 0) return r; else return o2.getKey().compareTo(o1.getKey()); } }); treeSet.addAll(map.entrySet()); System.out.println(treeSet); // output : [a=4, c=3, d=2, b=1]
另外,Groovy 中实现 sort map by value,当然本质是一样的,但却很简洁 :
用 groovy 中 map 的 sort 方法(需要 groovy 1.6),
def result = map.sort(){ a, b -> b.value.compareTo(a.value) }
如:
["a":3,"b":1,"c":4,"d":2].sort{ a,b -> a.value - b.value }
结果为: [b:1, d:2, a:3, c:4]
Python中也类似:
h = {"a":2,"b":1,"c":3} i = h.items() // i = [('a', 2), ('c', 3), ('b', 1)] i.sort(lambda (k1,v1),(k2,v2): cmp(v2,v1) ) // i = [('c', 3), ('a', 2), ('b', 1)]
以上这篇浅谈Java之Map 按值排序 (Map sort by value)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持PHP中文网。
更多浅谈Java之Map 按值排序 (Map sort by value)相关文章请关注PHP中文网!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

公司安全软件导致部分应用无法正常运行的排查与解决方法许多公司为了保障内部网络安全,会部署安全软件。...

将姓名转换为数字以实现排序的解决方案在许多应用场景中,用户可能需要在群组中进行排序,尤其是在一个用...

在使用IntelliJIDEAUltimate版本启动Spring...

系统对接中的字段映射处理在进行系统对接时,常常会遇到一个棘手的问题:如何将A系统的接口字段有效地映�...

在使用MyBatis-Plus或其他ORM框架进行数据库操作时,经常需要根据实体类的属性名构造查询条件。如果每次都手动...

Java对象与数组的转换:深入探讨强制类型转换的风险与正确方法很多Java初学者会遇到将一个对象转换成数组的�...

Redis缓存方案如何实现产品排行榜列表的需求?在开发过程中,我们常常需要处理排行榜的需求,例如展示一个�...

电商平台SKU和SPU表设计详解本文将探讨电商平台中SKU和SPU的数据库设计问题,特别是如何处理用户自定义销售属...
