需求:Map<key, value>中可以根据key, value 进行排序,由于 key 都是唯一的,可以很方便的进行比较操作,但是每个key 对应的value不是唯一的,有可能出现多个 相同的value对应key 是不一样的,所以需要采用不一样的方式。

详解:Map<key, value> 的目的是用来快速访问的存储结构。

通用的方法:

package com.compare;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.*; public class MapUtil { public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) { // 1、通过调用Map的entrySet()方法获取所有条目
List<Entry<K, V>> list = new ArrayList<>(map.entrySet());
// 2、创建自定义比较器以根据值对条目进行排序
// 3、将条目集转换为列表
// 4、sort()方法通过传递值比较器对条目列表进行排序, 也可以通过调用Collections.Sort(),之后的案例中会有介绍
list.sort(Entry.comparingByValue()); Map<K, V> result = new LinkedHashMap<>();
// 5、通过按排序顺序添加条目来创建LinkedHashMap。
for (Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
} return result;
} }
package com.compare;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Random; public class test { public static void main(String[] args) { Map<Integer, Integer> node_finalWeight = new HashMap(); node_finalWeight.put(5, 5);
node_finalWeight.put(35, 6);
node_finalWeight.put(45, 4);
node_finalWeight.put(25, 3);
node_finalWeight.put(20, 3); System.out.println("按值排序之前:" +node_finalWeight);
MapUtil mu = new MapUtil();
// 类实例化后直接调用方法
System.out.println("按值排序之后:" + mu.sortByValue(node_finalWeight) ); }
}

输出结果:

按值排序之前:{35=6, 20=3, 5=5, 25=3, 45=4}
按值排序之后:{20=3, 25=3, 45=4, 5=5, 35=6}

值得注意的是:

Map是java中的接口,Map.Entry是Map的一个内部接口。

Map提供了一些常用方法,如keySet()、entrySet()等方法。

keySet()方法返回值是Map中key值的集合;entrySet()的返回值也是返回一个Set集合,此集合的类型为Map.Entry。

Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry<K,V>。它表示Map中的一个实体(一个key-value对)。

Map.entrySet 方法返回映射的 collection 视图,其中的元素属于此类。获得映射项引用的唯一 方法是通过此 collection 视图的迭代器来实现。这些 Map.Entry 对象仅 在迭代期间有效;更确切地讲,如果在迭代器返回项之后修改了底层映射,则某些映射项的行为是不确定的,除了通过 setValue 在映射项上执行操作之外。

关于重写Java里面的比较器,这里有几篇文章写的不错:

https://www.baeldung.com/java-comparator-comparable

https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

https://www.geeksforgeeks.org/comparator-interface-java/

https://www.cnblogs.com/shizhijie/p/7657049.html

这里引用一下另外一个案例,作为参考:

package com.sortbyvalue;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
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; public class SortingByHashMap{ public static void main(String args[]) throws ParseException { // let's create a map with Java releases and their code names
HashMap<String, Integer> originalData = new HashMap<String, Integer>(); originalData.put("cangjie", 5);
originalData.put("minghuang", 7);
originalData.put("laozi", 5);
originalData.put("tangtaizong", 8);
originalData.put("simaqian", 9); System.out.println("HashMap before sorting: ");
Set<Entry<String, Integer>> entries = originalData.entrySet(); for(Entry<String, Integer> entry : entries){
System.out.println(entry.getKey() + " ==> " + entry.getValue());
} Comparator<Entry<String, Integer>> valueComparator = new Comparator<Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) {
Integer v1 = e1.getValue();
Integer v2 = e2.getValue();
return v1.compareTo(v2);
}
}; // Sort method needs a List, so let's first convert Set to List in Java
List<Entry<String, Integer>> listOfEntries = new ArrayList<Entry<String, Integer>>(entries); // sorting HashMap by values using comparator
Collections.sort(listOfEntries, valueComparator); LinkedHashMap<String, Integer> sortedByValue = new LinkedHashMap<String, Integer>(listOfEntries.size()); // copying entries from List to Map
for(Entry<String, Integer> entry : listOfEntries){
sortedByValue.put(entry.getKey(), entry.getValue());
} System.out.println("HashMap after sorting entries by values ");
Set<Entry<String, Integer>> entrySetSortedByValue = sortedByValue.entrySet(); for(Entry<String, Integer> mapping : entrySetSortedByValue){
System.out.println(mapping.getKey() + " ==> " + mapping.getValue());
} } }

附录一下如果想直接通过key 排序的话,可以借用一下TreeMap 的结构:

package com.sortbyvalue;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
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; public class SortingByHashMap{ public static void main(String args[]) throws ParseException { // let's create a map with Java releases and their code names
HashMap<String, Integer> originalData = new HashMap<String, Integer>(); originalData.put("cangjie", 5);
originalData.put("minghuang", 7);
originalData.put("laozi", 5);
originalData.put("tangtaizong", 8);
originalData.put("simaqian", 9); Map<String, Float> map = new TreeMap(originalData); // sort by keys
System.out.println(map); } }

输出结果:

{cangjie=5, laozi=5, minghuang=7, simaqian=9, tangtaizong=8}

接下来的介绍另外一种方法,可以当做复习知识点,略微烧脑,这部分的内容转自:

https://www.javacodegeeks.com/2017/09/java-8-sorting-hashmap-values-ascending-descending-order.html

1、通过调用Map.entrySet()方法获取条目集

2、通过调用stream()方法获取条目流

3、用比较器调用排序方法

4、使用Map.Entry.comparingByValue()比较器按值对条目进行排序

5、使用Collect()方法收集结果

6、使用Collectors.to Map()方法在另一个映射中获取结果。

7、提供LinkedHashMap::new到最后一个参数,强制它返回LinkedHashMap,以保留排序顺序。为了按降序排序,只需使用Java 8的Collections.reverse order()或Comparator.reverse()方法反转Comparator的顺序。

PS: 下面是具体的collect框架图,

实例:

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map; import static java.util.stream.Collectors.*;
import static java.util.Map.Entry.*; /*
* Java Program to sort a Map by values in Java 8
*
*/
public class Main { public static void main(String[] args) throws Exception { // a Map with string keys and integer values
Map<String, Integer> budget = new HashMap<>();
budget.put("clothes", 120);
budget.put("grocery", 150);
budget.put("transportation", 100);
budget.put("utility", 130);
budget.put("rent", 1150);
budget.put("miscellneous", 90); System.out.println("map before sorting: " + budget); // let's sort this map by values first
Map<String, Integer> sorted = budget
.entrySet()
.stream()
.sorted(comparingByValue())
.collect(
toMap(e -> e.getKey(), e -> e.getValue(), (e1, e2) -> e2,
LinkedHashMap::new)); System.out.println("map after sorting by values: " + sorted); // above code can be cleaned a bit by using method reference
sorted = budget
.entrySet()
.stream()
.sorted(comparingByValue())
.collect(
toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,
LinkedHashMap::new)); // now let's sort the map in decreasing order of value
sorted = budget
.entrySet()
.stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(
toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,
LinkedHashMap::new)); System.out.println("map after sorting by values in descending order: "
+ sorted);
} }

输出结果:

map before sorting: {grocery=150, utility=130, miscellneous=90, rent=1150, clothes=120, transportation=100}
map after sorting by values: {miscellneous=90, transportation=100, clothes=120, utility=130, grocery=150, rent=1150}
map after sorting by values in descending order: {rent=1150, grocery=150, utility=130, clothes=120, transportation=100, miscellneous=90}

同时,这里提到比较详细的步骤,有兴趣的可以批阅一下:

https://dzone.com/articles/how-to-sort-a-map-by-value-in-java-8

参考资料:

https://www.cnblogs.com/heganlin/p/5914892.html

https://tool.oschina.net/uploads/apidocs/jdk-zh/java/util/Map.Entry.html

https://www.javacodegeeks.com/2017/09/java-8-sorting-hashmap-values-ascending-descending-order.html

https://www.geeksforgeeks.org/sorting-a-hashmap-according-to-values/

https://www.java67.com/2015/01/how-to-sort-hashmap-in-java-based-on.html

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

https://www.jb51.net/article/90660.htm#comments

Java中Map<Key, Value>存储结构根据值排序(sort by values)的更多相关文章

  1. Java中关于泛型集合类存储的总结

    集合类存储在任何编程语言中都是很重要的内容,只因有这样的存储数据结构才让我们可以在内存中轻易的操作数据,那么在Java中这些存储类集合结构都有哪些?内部实现是怎么样?有什么用途呢?下面分享一些我的总结 ...

  2. java中map接口hashMap以及Enty之间的用法和关系

    java中map接口hashMap以及Enty之间的转换 首先说的是map接口: Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value ...

  3. java中Map,List与Set的差别

    java中Map,List与Set的差别 java集合的主要分为三种类型: Set(集) List(列表) Map(映射) 要深入理解集合首先要了解下我们熟悉的数组: 数组是大小固定的,而且同一个数组 ...

  4. Java中Map用法详解

    原文地址http://blog.csdn.net/guomutian911/article/details/45771621 原文地址http://blog.csdn.net/sunny2437885 ...

  5. Java中正负数的存储方式-正码 反码和补码

    Java中正负数的存储方式-正码 反码和补码 正码 我们以int 为例,一个int占用4个byte,32bits 0 存在内存上为 00000000 00000000 00000000 0000000 ...

  6. 将java中Map对象转为有相同属性的类对象(json作为中间转换)

    java中Map对象转为有相同属性的类对象(json作为中间转换) 准备好json转换工具类 public class JsonUtil { private static ObjectMapper o ...

  7. java中的TreeMap如何顺序按照插入顺序排序

    java中的TreeMap如何顺序按照插入顺序排序 你可以使用LinkedHashMap  这个是可以记住插入顺序的. 用LinkedHashMap吧.它内部有一个链表,保持插入的顺序.迭代的时候,也 ...

  8. JAVA中执行JavaScript代码并获取返回值

    JAVA中执行JavaScript代码并获取返回值 场景描述 实现思路 技术要点 代码实现 测试方法 运行结果 改进空间 场景描述 今天在CSDN上偶然看到一个帖子对于一段字符串 “var p=‘xx ...

  9. Java中Map根据键值(key)或者值(value)进行排序实现

    我们都知道,java中的Map结构是key->value键值对存储的,而且根据Map的特性,同一个Map中 不存在两个Key相同的元素,而value不存在这个限制.换句话说,在同一个Map中Ke ...

随机推荐

  1. C#搞个跨平台的桌面NES游戏模拟器

    支持Windows,Mac,Linux    NES模拟器内核源码来自 https://github.com/colinvella/EmuNes   他这边的源码功能很完善了的,支持视频录制,手柄,金 ...

  2. 文件上传bypass jsp内容检测的一些方法

    bx2=冰蝎2 前段时间渗透遇到了个检测jsp内容的,然后发现全unicode编码就可以绕过,但是对bx2马进行全编码他出现了一些错误,我尝试简单改了下,日站还是bx2操作舒服点 检测内容的话,这样直 ...

  3. 缓冲区溢出分析第08课:MS06-040漏洞研究——动态调试

    前言 经过上次的分析,我们已经知道了MS06-040漏洞的本质,那么这次我们就通过编程实现漏洞的利用. 编写漏洞利用程序的框架 这里我使用的是VC++6.0进行编写,需要将包含有漏洞的netapi32 ...

  4. UVA11384正整数序列(把123..变成0的最小步数)

    题意:      给定一个正整数n,你的任务是最少的操作次数把序列1 2 3 4 5...n中所有的数字都变成0,每次操作可以从序列中选择一个活多个整数,同时减去一个相同的正整数,比如 1 2 3可以 ...

  5. (3) arm 指令

    跳转指令1.1 B 跳转指令 B{cond} label 说明:如果条件cond满足,arm处理器将立即跳转到label指定的地址处继续执行.1.2 BL 带链接的跳转指令 BL{cond} labe ...

  6. 【python】Leetcode每日一题-删除有序数组中的重复项

    [python]Leetcode每日一题-删除有序数组中的重复项 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现一次 ,返回删除后数组的新长度. 不要 ...

  7. Day001 电脑常用快捷键

    电脑常用快捷键 Ctrl+C 复制 Ctrl+V 粘贴 Ctrl+A 全选 Ctrl+X 剪切 Ctrl+Z 撤销 Ctrl+S 保存 Alt+F4 关闭窗口(英雄联盟选英雄界面可以查看对面阵容(狗头 ...

  8. Linux基本内容

    当你学会开发完成一个项目之后,你就可以将项目进行上线,而且其实并不难,你需要先对Linux操作系统了解一下,博客下面的内容是基于CentOs7服务器. 购买服务器 参考链接 Linux宝塔面板 Lin ...

  9. Masm32sdk安装指南

    上一年学习win32汇编时用的masm32sdk不是最新版本的.因为最近准备继续学习win32汇编,所以准备安装最新的masm32sdk软件包.其中遇到了一些问题,从网上找了2个小时才搞定(宝宝心里苦 ...

  10. JVM虚拟机 类加载过程与类加载器

    目录 前言 类的生命周期 类加载过程 加载 连接 验证 准备 解析 初始化 类加载器 三大类加载器 双亲委派模型 概念 为什么要使用双亲委派模型 源码分析 反双亲委派模型 参考 前言 类装载器子系统是 ...