Java Map按值排序的正确姿势

简介: 在实际业务开发中,可能会遇到Java Map按值排序的需要

Java Map按值排序的常见思路是

1、 将map中的entry放到List中

2、 对List中的entry通过比较器按值排序

3 、将排序后的entry放到linkedhashmap中

Java 8利用Stream


import java.util.Collections;

import java.util.HashMap;

import java.util.LinkedHashMap;

import java.util.Map;

import static java.util.Map.Entry.comparingByValue;

import static java.util.stream.Collectors.toMap;

public class SortTest {

   public static void main(String[] args) throws Exception {

       // 创建一个字符串为Key,数字为值的map

       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("排序前: " + budget);

       // 按值排序 升序

       Map<String, Integer> sorted = budget

               .entrySet()

               .stream()

               .sorted(comparingByValue())

               .collect(

                       toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,

                               LinkedHashMap::new));

       System.out.println("升序按值排序后的map: " + sorted);

       // 按值排序降序

       sorted = budget

               .entrySet()

               .stream()

               .sorted(Collections.reverseOrder(comparingByValue()))

               .collect(

                       toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,

                               LinkedHashMap::new));

       System.out.println("降序按值排序后的map: " + sorted);

   }

}

可以封装成工具类


/**

* Map排序工具类

*

* @author liuwangyanghdu@163.com  明明如月

*/

public class MapSortUtil {

 

   private static Comparator<Map.Entry> comparatorByKeyAsc = (Map.Entry o1, Map.Entry o2) -> {

       if (o1.getKey() instanceof Comparable) {

           return ((Comparable) o1.getKey()).compareTo(o2.getKey());

       }

       throw new UnsupportedOperationException("键的类型尚未实现Comparable接口");

   };

   private static Comparator<Map.Entry> comparatorByKeyDesc = (Map.Entry o1, Map.Entry o2) -> {

       if (o1.getKey() instanceof Comparable) {

           return ((Comparable) o2.getKey()).compareTo(o1.getKey());

       }

       throw new UnsupportedOperationException("键的类型尚未实现Comparable接口");

   };

   private static Comparator<Map.Entry> comparatorByValueAsc = (Map.Entry o1, Map.Entry o2) -> {

       if (o1.getValue() instanceof Comparable) {

           return ((Comparable) o1.getValue()).compareTo(o2.getValue());

       }

       throw new UnsupportedOperationException("值的类型尚未实现Comparable接口");

   };

   private static Comparator<Map.Entry> comparatorByValueDesc = (Map.Entry o1, Map.Entry o2) -> {

       if (o1.getValue() instanceof Comparable) {

           return ((Comparable) o2.getValue()).compareTo(o1.getValue());

       }

       throw new UnsupportedOperationException("值的类型尚未实现Comparable接口");

   };

   /**

    * 按键升序排列

    */

   public static <K, V> Map<K, V> sortByKeyAsc(Map<K, V> originMap) {

       if (originMap == null) {

           return null;

       }

       return sort(originMap, comparatorByKeyAsc);

   }

   /**

    * 按键降序排列

    */

   public static <K, V> Map<K, V> sortByKeyDesc(Map<K, V> originMap) {

       if (originMap == null) {

           return null;

       }

       return sort(originMap, comparatorByKeyDesc);

   }

   /**

    * 按值升序排列

    */

   public static <K, V> Map<K, V> sortByValueAsc(Map<K, V> originMap) {

       if (originMap == null) {

           return null;

       }

       return sort(originMap, comparatorByValueAsc);

   }

   /**

    * 按值降序排列

    */

   public static <K, V> Map<K, V> sortByValueDesc(Map<K, V> originMap) {

       if (originMap == null) {

           return null;

       }

       return sort(originMap, comparatorByValueDesc);

   }

   private static <K, V> Map<K, V> sort(Map<K, V> originMap, Comparator<Map.Entry> comparator) {

       return originMap.entrySet()

               .stream()

               .sorted(comparator)

               .collect(

                       Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,

                               LinkedHashMap::new));

   }

}

测试类


package com.chujianyun.common.map;

import org.junit.jupiter.api.BeforeAll;

import org.junit.jupiter.api.Test;

import org.junit.jupiter.api.TestInstance;

import java.util.HashMap;

import java.util.Map;

/**

* Map排序工具类

*

* @author liuwangyanghdu@163.com  明明如月

*/

@TestInstance(TestInstance.Lifecycle.PER_CLASS)

class MapSortUtilTest {

   // 创建一个字符串为Key,数字为值的map

   Map<String, Integer> budget = new HashMap<>();

   @BeforeAll

   public void init() {

       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("排序前: " + budget);

   }

   @Test

   void sortByKeyAsc() {

       System.out.println("按键升序" + MapSortUtil.sortByKeyAsc(budget));

   }

   @Test

   void sortByKeyDesc() {

       System.out.println("按键降序" + MapSortUtil.sortByKeyDesc(budget));

   }

   @Test

   void sortByValueAsc() {

       System.out.println("按值升序" + MapSortUtil.sortByValueAsc(budget));

   }

   @Test

   void sortByValueDesc() {

       System.out.println("按值降序" + MapSortUtil.sortByValueDesc(budget));

   }

}


Java 7版本


import java.util.*;

import java.lang.*;

public class GFG {

//  hashmap按值排序

public static HashMap<String, Integer> sortByValue(HashMap<String, Integer> hm)

{

 // HashMap的entry放到List中

 List<Map.Entry<String, Integer> > list =

  new LinkedList<Map.Entry<String, Integer> >(hm.entrySet());

 //  对List按entry的value排序

 Collections.sort(list, new Comparator<Map.Entry<String, Integer> >() {

  public int compare(Map.Entry<String, Integer> o1,

      Map.Entry<String, Integer> o2)

  {

   return (o1.getValue()).compareTo(o2.getValue());

  }

 });

 

 // 将排序后的元素放到LinkedHashMap中

 HashMap<String, Integer> temp = new LinkedHashMap<String, Integer>();

 for (Map.Entry<String, Integer> aa : list) {

  temp.put(aa.getKey(), aa.getValue());

 }

 return temp;

}


public static void main(String[] args)

{

 HashMap<String, Integer> hm = new HashMap<String, Integer>();

 // 填充测试数据

 hm.put("Math", 98);

 hm.put("Data Structure", 85);

 hm.put("Database", 91);

 hm.put("Java", 95);

 hm.put("Operating System", 79);

 hm.put("Networking", 80);

 Map<String, Integer> hm1 = sortByValue(hm);

 // 打印按值排序后的数据

 for (Map.Entry<String, Integer> en : hm1.entrySet()) {

  System.out.println("Key = " + en.getKey() +

     ", Value = " + en.getValue());

 }

}

}

参考文章:


1、 Java 8 – Sorting HashMap by values in ascending and descending order


2、 Sort a Map<Key, Value> by values


3、Sorting a Hashmap according to values



如果文章对你有帮助,欢迎点赞,关注,你的鼓励是我创作的最大动力!!

————————————————

版权声明:本文为CSDN博主「明明如月学长」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/w605283073/article/details/88754599

相关文章
|
3月前
|
存储 安全 Java
Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
【10月更文挑战第17天】Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
96 2
|
3月前
|
存储 Java
告别混乱!用Java Map优雅管理你的数据结构
【10月更文挑战第17天】在软件开发中,随着项目复杂度增加,数据结构的组织和管理至关重要。Java中的Map接口提供了一种优雅的解决方案,帮助我们高效、清晰地管理数据。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,有效提升了代码质量和维护性。
107 2
|
17天前
|
Java 程序员
Java 排序神器:Comparable 和 Comparator 该怎么选?
嗨,大家好,我是小米!今天和大家聊一聊Java社招面试中常考的经典问题——Comparable和Comparator的区别。Comparable定义对象的自然排序,适用于单一固定的排序规则;Comparator则是策略接口,用于定义自定义排序规则,适用于多样化或多变的排序需求。掌握这两者的区别是理解Java排序机制的基础,也是面试中的加分题。结合实际项目场景深入探讨它们的应用,能更好地打动面试官。如果你觉得有帮助,欢迎点赞、收藏、分享,期待你的一键三连!我们下期见~ 我是小米,一个喜欢分享技术的程序员,关注我的微信公众号“软件求生”,获取更多技术干货!
43 20
|
2月前
|
存储 Java API
Java交换map的key和value值
通过本文介绍的几种方法,可以在Java中实现Map键值对的交换。每种方法都有其优缺点,具体选择哪种方法应根据实际需求和场景决定。对于简单的键值对交换,可以使用简单遍历法或Java 8的Stream API;对于需要处理值不唯一的情况,可以使用集合存储或Guava的Multimap。希望本文对您理解和实现Java中的Map键值对交换有所帮助。
56 1
|
3月前
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第19天】本文介绍了Java编程中重要的数据结构——Map,通过问答形式讲解了Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的使用和性能优化技巧,适合初学者和进阶者学习。
110 4
|
3月前
|
存储 Java API
优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。
【10月更文挑战第19天】本文介绍了如何优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。内容包括Map的初始化、使用Stream API处理Map、利用merge方法、使用ComputeIfAbsent和ComputeIfPresent,以及Map的默认方法。这些技巧不仅提高了代码的可读性和维护性,还提升了开发效率。
149 3
|
3月前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
87 3
|
3月前
|
存储 缓存 安全
在Java的Map家族中,HashMap和TreeMap各具特色
【10月更文挑战第19天】在Java的Map家族中,HashMap和TreeMap各具特色。HashMap基于哈希表实现,提供O(1)时间复杂度的高效操作,适合性能要求高的场景;TreeMap基于红黑树,提供O(log n)时间复杂度的有序操作,适合需要排序和范围查询的场景。两者在不同需求下各有优势,选择时需根据具体应用场景权衡。
44 2
|
3月前
|
存储 安全 Java
Java Map新玩法:深入探讨HashMap和TreeMap的高级特性
【10月更文挑战第19天】Java Map新玩法:深入探讨HashMap和TreeMap的高级特性,包括初始容量与加载因子的优化、高效的遍历方法、线程安全性处理以及TreeMap的自然排序、自定义排序、范围查询等功能,助你提升代码性能与灵活性。
35 2
|
3月前
|
存储 Java 开发者
Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效
【10月更文挑战第19天】在软件开发中,随着项目复杂度的增加,数据结构的组织和管理变得至关重要。Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,帮助开发者告别混乱,提升代码质量。
38 1