在上一篇文章中,我向您展示了如何在 Java 8 中通过键对 Map 进行排序,今天,我将教您使用 Java 如何通过值对 Map 进行排序 8 个特征,例如lambda 表达式、方法引用、流和添加到 java.util.Comparator 和 Map.Entry 类中的新方法。为了对任何Map进行排序,例如HashMap、Hashtable、LinkedHashMap、TreemMap,甚至ConcurrentHashMap,您可以先使用 entrySet() 方法获取条目集,然后可以通过调用流()方法。 entrySet() 方法返回一个 Set,它继承了 java.util.Collection 类的 stream() 方法。获得流后,您只需调用 sorted() 方法即可使用 Comparator 对 Stream 中可用的所有 Map.Entry 对象进行排序。
为了按值比较 Map 的条目,您可以使用 java.util.Map.Entry 类中新添加的 Map.Entry.comparingByValue() 方法。
这是我们在上一篇文章中使用的 comparingByKey() 方法的对应方法。这两种方法都被重载以与 Comparable 和 Comparator 对象一起使用。
一旦你对流进行排序,你就可以做任何你想做的事情,例如如果您只想按排序顺序打印键、值或条目,只需使用 forEach() 方法,或者如果您想要一个按值排序的 Map,则可以使用 collect() 方法流类。
此方法接受 Collector 并允许您将 Stream 的所有元素捕获到您想要的任何集合中。例如,如果您想要一个排序的Map,那么您可以使用 java.util.stream.Collectors 类的 toMap() 方法。
这个方法被重载并提供了几个选择,例如,你可以在任何类型的Map中收集条目,或者你也可以指定你想要的Map类型,例如为了保持条目排序,我们将使用 LinkedHashMap。它还允许您在相同值的情况下打破联系,例如你可以按照你想要的顺序排列它们。
顺便说一句,如果你很好奇,你也可以看看 Pluralsight 的 From Collections to Streams in Java 8 Using Lambda Expressions 课程来了解更多关于 Java 8 的新特性,这是特定于集合框架的。
简而言之,这里是在 Java 8 中按值对 HashMap 进行排序的确切步骤,假设您已经有一个 map 对象
执行此步骤后,您将获得一个按值排序的Map。现在您已经了解了理论和步骤,让我们看看下一节中的代码示例以正确理解它。
这是我们完整的 Java 程序,使用 Java 8 功能按值对 Map 进行排序,例如通过使用接口上的默认方法和静态方法对 Java 8 中的现有类进行新方法的改进。在这个例子中,我有一个项目Map及其费用的Map,例如租金,公用事业,交通等。Map key是String,代表item,value是Integer,代表费用。我们的任务是按值对 Map 进行排序,找出哪个项目花费最多,并按值的降序打印所有项目。
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); } } 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进行排序之前,Map在值方面具有随机顺序,但首先,我们按值的升序对它们进行排序,然后我们按值的降序对同一Map进行排序,这就是租金排在第一位的原因,因为它让我们付出了最高的代价。
1)使用static import来缩短代码,你可以静态导入Map.Entry和Collectors类。
2) 尽可能使用方法引用代替 lambda 表达式。如果您不熟悉,请参阅这篇文章,了解有关如何在 Java 8 中将 lambda 表达式转换为方法引用的更多信息。
这就是关于如何在 Java 8 中按值对 Map 进行排序。您可以看到使用添加到现有类的新方法对 Map 进行排序非常容易。由于 JDK 8 的默认方法特性,所有这些都是可能的,它允许您向现有类添加新方法。在此增强之前,在 Java 中不可能不破坏现有的接口客户端,因为一旦向接口添加新方法,它的所有客户端都必须实现它。如果方法是默认的或静态的,则不再需要这样做,因为它们不是抽象的而是具体的方法。
Java 8 的新特性
真正不耐烦的 Java SE 8
在 Java 8 中使用 Lambda 表达式从集合到流
如果你有兴趣了解更多关于 Java 8 的新特性,这里是我之前的文章,涵盖了 Java 8 的一些重要概念:
感谢您到目前为止阅读本文。如果您喜欢这篇文章,请与您的朋友和同事分享。如果您有任何问题或建议,请发表评论。
标签2: Java教程地址:https://www.cundage.com/article/jcg-java-8-sorting-hashmap-values-ascending-descending-order.html