Java 8 –按值对HashMap进行升序和降序排序

在上一篇文章中,我向您展示了如何通过键对Java 8中的Map进行排序 ,今天,我将教您如何使用Java 8功能(例如,lambda表达式,方法引用,流和新方法) 按值对Map进行排序。添加到java.util.Comparator和Map.Entry类中。 为了对任何Map进行排序,例如HashMap ,Hashtable,LinkedHashMap,TreemMap甚至ConcurrentHashMap ,您可以首先使用entrySet()方法获取条目集,然后可以通过调用stream()方法获取流。 entrySet()方法返回一个Set,该Set从java.util.Collection类继承stream()方法。 一旦获得流,就可以调用sorted()方法,该方法可以使用Comparator对Stream中可用的所有Map.Entry对象进行排序。

为了按值比较Map的条目,可以使用java.util.Map.Entry类中新添加的Map.Entry.comparingByValue()方法。

这与我们在上一篇文章中使用过的compareByKey()方法相对应。 这两种方法都被重载以与Comparable和Comparator对象一起使用。

对流进行排序后,您可以执行任何操作,例如,如果您只想按排序的顺序打印键,值或条目,则只需使用forEach()方法,或者如果要按值对Map进行排序,则可以您可以使用流类的collect()方法。

此方法接受收集器,并允许您将Stream的所有元素捕获到所需的任何集合中。 例如,如果要排序的地图,则可以使用java.util.stream.Collectors类的toMap()方法。

此方法是重载的,并提供了两种选择,例如,您可以收集任何类型的地图中的条目,也可以指定所需的地图类型,例如,为了使条目保持排序,我们将使用LinkedHashMap 。 它还允许您在相同值的情况下打破平局,例如,可以按想要的顺序排列它们。

顺便说一句,如果您好奇的话,您还可以查看Pluralsight的《 从Java 8使用Lambda表达式到从流到集合》课程,以了解有关特定于集合框架的Java 8新功能的更多信息。

简而言之,以下是在Java 8中按值升序或降序对HashMap进行排序的确切步骤,假设您已经有一个map对象

  1. 通过调用Map.entrySet()方法获取条目集
  2. 通过调用stream()方法获取条目流
  3. 用Comparator调用排序的方法
  4. 使用Map.Entry.comparingByValue()比较器按值对条目进行排序
  5. 使用collect()方法收集结果
  6. 使用Collectors.toMap()方法在另一个Map中获取结果。
  7. 在最后一个参数中提供LinkedHashMap :: new,以强制其返回LinkedHashMap,以保留排序顺序
  8. 为了按降序排序,只需使用Java 8的Collections.reverseOrder()或Comparator.reverse()方法来颠倒Comparator的顺序,有关添加到关键Java类中的新方法的完整列表,请参阅Java SE 8,对于Really Im耐心 。例如Java Collection Framework,String和Comparator等。

完成此步骤后,您将获得一个按值排序的Map。 现在您已经了解了理论和步骤,现在让我们看下一节中的代码示例以使其正确。

Java程序按值对地图排序

这是我们完整的Java程序,使用Java 8功能按值对Map进行排序,例如,通过使用接口上的默认方法和静态方法对Java 8中的现有类进行开发,从而对Java 8中现有类的新方法进行了排序。 在此示例中,我获得了项目地图及其费用(例如租金,公用事业,交通等)的Map。Map关键字是String ,代表项目,值是Integer,即费用。 我们的任务是按值对“地图”进行排序,以找出哪个项目花费最多,并按值的降序打印所有项目。

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 valuesMap<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 firstMap<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 referencesorted = 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 valuesorted = 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);}}Output
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}

您可以看到,在对地图进行排序之前,按照值将其随机排列,但是首先,我们对它们进行了按值的升序排序,然后对相同的Map进行了按值的降序排序,这就是为什么租金排在第一位的原因,它使我们付出了最高的代价。

一些技巧

1)使用静态导入可以缩短代码,可以静态导入Map.Entry和Collectors类。

2)尽可能使用方法引用代替lambda表达式。 请参阅本文章以了解更多有关如何lambda表达式转换为方法的引用在Java中8,如果你不熟悉的。

这就是如何在Java 8中按值对Map进行排序的全部内容。 您可以看到,使用添加到现有类的新方法对Map进行排序非常容易。 一切皆有可能,因为JDK 8的默认方法功能使您可以向现有类添加新方法。 在进行此增强之前,在Java中不破坏接口的现有客户端是不可能的,因为一旦将新方法添加到接口中,它的所有客户端都必须实现它。 如果方法是默认方法或静态方法,则不再需要此方法,因为它们不是抽象方法而是具体方法。

进一步阅读

Java 8的新增功能

Java SE 8实在不耐烦

使用Lambda表达式从Java 8中的集合到流

相关的Java 8教程

如果您有兴趣学习有关Java 8的新功能的更多信息,这是我以前的文章,介绍Java 8的一些重要概念:

  • 从零开始学习Java 8的5本书( 书籍 )
  • Java 8中的默认方法是什么? ( 示例 )
  • 如何在Java 8中连接String( 示例 )
  • 如何在Java 8中使用filter()方法( 教程 )
  • 如何在Java 8中使用LocalDateTime格式化/解析日期? ( 教程 )
  • 如何在Java 8中使用Stream类( 教程 )
  • 如何在Java 8中将列表转换为Map( 解决方案 )
  • Java 8中抽象类和接口之间的区别? ( 回答 )
  • Java 8中20个日期和时间的示例( 教程 )
  • 如何在Java 8中使用peek()方法( 示例 )
  • 如何在Java 8中按键对地图排序? ( 示例 )
  • 如何在Java 8中按值对may进行排序? ( 示例 )
  • Java 8中的Optionals的10个示例? ( 示例 )

感谢您到目前为止阅读本文。 如果您喜欢这篇文章,请与您的朋友和同事分享。 如果您有任何疑问或建议,请发表评论。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/349250.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scrcpy投屏_scrcpy 使用教程:将安卓设备投屏到 PC 端

阿拉平平读完需要6分钟速读仅需 2 分钟scrcpy 是一款开源的安卓设备投屏工具&#xff0c;通过 USB 或 Wi-Fi 与设备连接后就可以在 PC 端操作安卓设备&#xff0c;无需 root 权限且支持多平台运行。本文将演示如何使用 scrcpy 进行投屏操作。1. 下载安装到 Releases 下载最新的…

打砖块小游戏php程序,利用原生js实现html5打砖块小游戏(代码示例)

本篇文章给大家通过代码示例介绍一下利用原生js实现html5打砖块小游戏的方法。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对大家有所帮助。前言PS&#xff1a;本次项目中使用了大量 es6 语法&#xff0c;故对于 es6 语法不太熟悉的小伙伴最好能先了…

si9000阻抗匹配计算_如何在设计之初计算出两层PCB板差分线的阻抗,线宽,间距...

最近在设计一款两层板PCB。板上一些高速信号线&#xff0c;分别是MIMP接口的差分线和USB2.0的差分线。既然是高速线&#xff0c;那么就需要设计成阻抗匹配走线。MIMP差分线需要做100ohm匹配&#xff0c;USB线需要做90ohm匹配。差分线阻抗的计算主要跟线宽&#xff0c;间距&…

jax-ws cxf_Apache CXF – JAX-WS –简单教程

jax-ws cxf许多Java开发人员都认为Web Service实现的任务艰巨-好吧&#xff0c;没有人能真正责怪他们&#xff0c;尤其是在企业应用程序开发的多年中&#xff0c;这给开发和设计带来了很多复杂性。 对于某些人来说&#xff0c;了解它是构建完整的企业应用程序的下一步-Web服务-…

写屏障是什么_面试官为什么问内存模型总离不开final关键字,该如何应对?

Java 语言的每个关键字都设计的很巧妙&#xff0c;金雕玉琢&#xff0c;只有深度钻研其中&#xff0c;才知其中懊悔&#xff0c;本文带领大家一起深入理解 Java 内存模型之 final。加我微信好友的不要着急&#xff0c;手机没电了&#xff0c;等我借个充电器之后&#xff0c;再一…

非静态方法可以访问Java中的静态变量/方法吗?

“非静态方法可以访问静态变量或调用静态方法”是Java中有关静态修饰符的常见问题之一&#xff0c;答案是&#xff0c; 是的 &#xff0c;非静态方法可以访问静态变量或调用静态方法。 Java中的方法。 这没有问题&#xff0c;因为有静态成员&#xff0c;即静态变量和静态方法都…

which oracle linux,(总结)Linux下Oracle11gR2的ORA-00845错误解决方法

PS&#xff1a;前些时间一台演示环境的Oracle 11g for Linux不知什么原因&#xff0c;启动不起来&#xff0c;报错ORA-00845。搜索了下&#xff0c;这个问题是由于设置SGA的大小超过了操作系统/dev/shm的大小。当时解决了没空写总结&#xff0c;今天有点空&#xff0c;总结分享…

oracle存储过程深入,深入了解oracle存储过程的优缺点

定义&#xff1a;存储过程(Stored Procedure )是一组为了完成特定功能的SQL 语句集&#xff0c;经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象&#xff0c;任何一个设计良好的数据库应用程…

如何在Java 8中使用LocalDateTime格式化/解析日期-示例教程

Java项目中的常见任务之一是将日期格式化或解析为String&#xff0c;反之亦然。 解析日期表示您有一个表示日期的字符串&#xff0c;例如“ 2017-08-3”&#xff0c;并且要将其转换为表示Java中日期的对象&#xff0c;例如Java 8之前版本中的java.util.Date以及LocalDate或Loca…

如何获取当前刀具号_数控刀具的选用原则,如何使用数控刀具?一文全面介绍数控刀具...

数控刀具选用概述学习数控相关知识&#xff0c;最基础的是认识和了解刀具的材料以及选用原则&#xff0c;我们应当了解数控刀具的种类及特点、如何正确选择和使用数控加工刀具&#xff1b;学会根据被加工材料来合理选择数控刀具的材料和切削参数。选用原则&#xff1a;数控车床…

Java命令行界面(第27部分):cli-parser

CLI Parser最初托管在Google Code上&#xff0c;现在已存档在Google Code上 &#xff0c;现在可以在GitHub上使用 。 归档的Google Code项目页面将CLI解析器描述为“使用非常简单&#xff0c;非常小的依赖项”&#xff0c;它使用注释“使非常简洁的主要方法不需要知道如何解析带…

使用2.26内核的linux,介绍linux 2.6.9-42内核升级到linux 2.6.26-42的方法

介绍linux 2.6.9-42内核升级到linux 2.6.26-42的方法来源&#xff1a;互联网作者&#xff1a;佚名时间&#xff1a;2013-04-10 13:32这篇升级Linux内容的文章&#xff0c;是基于Red Hat的Linux版本&#xff0c;从linux 2.6.9-42内核升级到linux 2.6.26-42的方法&#xff0c;对于…

Java命令行界面(第1部分):Apache Commons CLI

尽管我通常使用Groovy编写要从命令行运行的JVM托管脚本&#xff0c;但是有时候我需要解析Java应用程序中的命令行参数&#xff0c;并且有很多库可供Java开发人员用来解析命令行参数。 在本文中&#xff0c;我将介绍这些Java命令行解析库中最著名的一种&#xff1a; Apache Comm…

丙烯怎么做成流体丙烯_韧性好强度高的聚丙烯复合材料怎么做?让人工智能来帮忙...

01背景介绍聚丙烯(PP)是一种应用广泛的通用塑料&#xff0c;价格便宜、力学性能好、热稳定性高&#xff0c;在机械、汽车、电子电器、建筑、纺织、包装和食品工业等领域应用广泛。聚丙烯韧性和冲击强度不高&#xff0c;限制了它的应用。加入热塑性弹性体(TPE)&#xff0c;如苯乙…

vivado安装_Vivado下载与安装指南

Vivado下载与安装指南目前&#xff0c;vivado已推出2019.1版本&#xff0c;实验室所安装的为2018.3版本&#xff0c;由于软件向下兼容的特性&#xff0c;建议安装2018版本&#xff0c;若安装2019版本&#xff0c;请自带笔记本&#xff0c;安装过程与之前没有差别&#xff0c;这…

嵌入式基于linux电机控制器,基于嵌入式Linux的移动机器人控制系统

使用select机制监控是否语音识别结果&#xff0c;在超出等待时间后&#xff0c;会退出等待并重新初始化语音模块LD3320&#xff0c;释放公共资源&#xff0c;这样也使得系统能够及时响应LD3320的MP3播放功能&#xff0c;避免了在长时间没有语音识别结果时&#xff0c;系统进入卡…

windows server 驱动精灵_还在用Windows文件共享?我来教你一键摆脱Windows海量小文件使用和备份的噩梦...

每当我问到客户&#xff0c;“你用什么存储产品作为文件共享&#xff1f;”经常听到的一个答案(自豪滴)是&#xff0c;“文件共享需要存储么&#xff1f;我们用Windows就可以做到。”Windows就是个百宝箱&#xff0c;什么都能往里装&#xff0c;就像你家冰箱一样。众所周知&…

pb 应用 迁移 linux_功能化生物炭应用研究取得系列进展

土壤营养元素流失、重金属污染是当前全球面临的突出环境问题。生物炭因其具有比表面积较大、吸附性能高和成本低等优点而在环境修复领域日益受到广泛关注&#xff0c;被作为水处理吸附剂、土壤修复改良剂广泛应用于农业土壤改良和环境中重金属的修复和钝化。但通常情况下&#…

Java命令行界面(第26部分):CmdOption

由于Tweet&#xff0c;我了解了本系列中第26个基于Java的功能强大的库&#xff0c;该库用于解析命令行参数 。 CmdOption在其GitHub主页上被描述为“一个通过注释配置的&#xff0c;用于Java 5应用程序的简单注释驱动的命令行解析器工具包。” 该项目的副标题是“命令行解析从未…

vector c++ 赋值_面对拷贝赋值时发生的自我赋值的正确态度时接受而不是防止

C.62: Make copy assignment safe for self-assignmentC.62:保证拷贝赋值对自我赋值安全Reason(原因)If x x changes the value of x, people will be surprised and bad errors will occur (often including leaks).如果xx改变了x的值&#xff0c;人们会觉得很奇怪&#xff0…