Sort Map by Value in Java

实际项目或者业务当中,经常会有需求要求对 hashmap 按值排序,并返回指定顺序的 TopN 个元素,今天就来分享下具体的代码及其原理实现。

package com.bj.test.top10;

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.NavigableMap;
import java.util.TreeMap;

public class SortMapByValue {

	// output the values is descending
	public static <K, V extends Comparable<? super V>> List<Entry<K, V>> sortMapByValuesTopN(Map<K, V> map, int topN) {

		List<Entry<K, V>> sortedEntries = new ArrayList<Entry<K, V>>(map.entrySet());

		Collections.sort(sortedEntries, new Comparator<Entry<K, V>>() {
			@Override
			public int compare(Entry<K, V> e1, Entry<K, V> e2) {
				return e2.getValue().compareTo(e1.getValue());
			}
		});

		int listLen = sortedEntries.size();
		// System.out.println(listLen);
		while (topN > 0 && listLen > topN) {
			listLen--;
			sortedEntries.remove(listLen);
		}
		return sortedEntries;
	}

	// output the values is descending
	public static <K, V extends Comparable<? super V>> List<Entry<K, V>> sortMapByValues(Map<K, V> map) {

		List<Entry<K, V>> sortedEntries = new ArrayList<Entry<K, V>>(map.entrySet());

		Collections.sort(sortedEntries, new Comparator<Entry<K, V>>() {
			@Override
			public int compare(Entry<K, V> e1, Entry<K, V> e2) {
				return e2.getValue().compareTo(e1.getValue());
			}
		});

		return sortedEntries;
	}

	public static void printMap(Map<String, Integer> map) {
		for (Map.Entry<String, Integer> entry : map.entrySet()) {
			System.out.println("[Key] : " + entry.getKey() + " [Value] : " + entry.getValue());
		}
	}

	public static Map list2Map(List list) {
		// Convert sorted map back to a Map
		Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
		for (Iterator<Map.Entry<String, Integer>> it = list.iterator(); it.hasNext();) {
			Map.Entry<String, Integer> entry = it.next();
			sortedMap.put(entry.getKey(), entry.getValue());
		}
		return sortedMap;
	}

	public static void main(String[] args) {

		// NavigableMap descMap = new TreeMap<>().descendingMap();
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("A", 34);
		map.put("B", 25);
		map.put("C", 50);
		map.put("D", 50); // "duplicate" value
		map.put("z", 10);
		map.put("b", 5);
		map.put("a", 6);
		map.put("c", 20);
		map.put("d", 1);
		map.put("e", 7);
		map.put("y", 8);
		map.put("n", 99);
		map.put("j", 50);
		map.put("m", 2);
		map.put("f", 9);

		System.out.println("返回前 10 个 value 最大的键值对:");
		printMap(list2Map(sortMapByValuesTopN(map, 10)));
		System.out.println(sortMapByValuesTopN(map, 10));
		System.out.println(list2Map(sortMapByValuesTopN(map, 10)).get("n"));

		System.out.println("++++++++++++++++++++++++++++++++++++++\n");
		System.out.println("返回排序之后的键值对:");
		printMap(list2Map(sortMapByValues(map)));
	}
}



// 结果:
返回前 10 个 value 最大的键值对:
[Key] : n [Value] : 99
[Key] : C [Value] : 50
[Key] : D [Value] : 50
[Key] : j [Value] : 50
[Key] : A [Value] : 34
[Key] : B [Value] : 25
[Key] : c [Value] : 20
[Key] : z [Value] : 10
[Key] : f [Value] : 9
[Key] : y [Value] : 8
[n=99, C=50, D=50, j=50, A=34, B=25, c=20, z=10, f=9, y=8]
99
++++++++++++++++++++++++++++++++++++++

返回排序之后的键值对:
[Key] : n [Value] : 99
[Key] : C [Value] : 50
[Key] : D [Value] : 50
[Key] : j [Value] : 50
[Key] : A [Value] : 34
[Key] : B [Value] : 25
[Key] : c [Value] : 20
[Key] : z [Value] : 10
[Key] : f [Value] : 9
[Key] : y [Value] : 8
[Key] : e [Value] : 7
[Key] : a [Value] : 6
[Key] : b [Value] : 5
[Key] : m [Value] : 2
[Key] : d [Value] : 1

Refer:

[1] Sort map by value

http://www.leveluplunch.com/java/examples/sort-order-map-by-values/

[2] How to sort a Map in Java

http://www.mkyong.com/java/how-to-sort-a-map-in-java/

[3] Sort a Map<Key, Value> by values (Java)

http://stackoverflow.com/questions/109383/sort-a-mapkey-value-by-values-java

    Sorting the Map<Key,Value> in descending order based on the value [duplicate]

http://stackoverflow.com/questions/11647889/sorting-the-mapkey-value-in-descending-order-based-on-the-value

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏老马说编程

(66) 理解synchronized / 计算机程序的思维逻辑

上节我们提到了多线程共享内存的两个问题,一个是竞态条件,另一个是内存可见性,我们提到,解决这两个问题的一个方案是使用synchronized关键字,本节就来讨论...

28650
来自专栏Aloys的开发之路

制作Aspose CHM文档的过程记录

最近公司需要使用Aspose组件开发相关内容,但是网上找不到理想的参考文档,官网访问速度也慢的可以。所以打算自己做份CHM文档,做的过程中遇到很多困难,这里记录...

225100
来自专栏Aloys的开发之路

Calendar类中add/set/roll方法的区别

Calendar类中有三个方法更改日期的某个字段:set()、add() 和 roll()。 set(f, value) 将日历字段 f 更改为 value。此...

26290
来自专栏java达人

Java虚拟机

1、Java虚拟机是什么 “Java虚拟机“可以指三种不同的东西 抽象规范 一个具体的实现 一个运行中的虚拟机实例 当运行一个Java程序的同时,也就是在运行一...

298100
来自专栏java达人

HashMap的工作原理

HashMap的工作原理是近年来常见的Java面试题。几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和Hash...

21270
来自专栏老马说编程

(67) 线程的基本协作机制 (上) / 计算机程序的思维逻辑

上节介绍了多线程之间竞争访问同一个资源的问题及解决方案synchronized,我们提到,多线程之间除了竞争,还经常需要相互协作,本节就来介绍Java中多线程协...

22360
来自专栏java达人

Java开发者编写SQL语句时常见的10种错误

Java开发者对于面向对象编程思维与命令行编程思维的协调程度,取决于他们如下几种能力的水平: 1. 技巧(任何人都可以编写命令行形式的代码) 2. 教条(有的...

30650
来自专栏java达人

java枚举类型enum的使用

最近跟同事讨论问题的时候,突然同事提到我们为什么java 中定义的常量值不采用enmu 枚举类型,而采用public final static 类型来定义呢?以...

259100
来自专栏java达人

Java 枚举7常见种用法

用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl…. 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,...

28880
来自专栏老马说编程

(60) 随机读写文件及其应用 - 实现一个简单的KV数据库 / 计算机程序的思维逻辑

查看历史文章,请点击上方链接关注公众号。 57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读...

25960

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励