使用Java8 Stream API对Map按键或值进行排序

一、什么是Java 8 Stream

使用Java 8 Streams,我们可以按键和按值对映射进行排序。下面是它的工作原理:

  1. 将Map或List等集合类对象转换为Stream对象
  2. 使用Streams的sorted()方法对其进行排序
  3. 最终将其返回为LinkedHashMap(可以保留排序顺序)

sorted()方法以Comparator作为参数,从而可以按任何类型的值对Map进行排序。如果对Comparator不熟悉,可以看本号前几天的文章,有一篇文章专门介绍了使用Comparator对List进行排序。

二、学习一下HashMap的merge()函数

在学习Map排序之前,有必要讲一下HashMap的merge()函数,该函数应用场景就是当Key重复的时候,如何处理Map的元素值。这个函数有三个参数:

  • 参数一:向map里面put的键
  • 参数二:向map里面put的值
  • 参数三:如果键发生重复,如何处理值。可以是一个函数,也可以写成lambda表达式。
        String k = "key";
        HashMap<String, Integer> map = new HashMap<String, Integer>() {{
            put(k, 1);
        }};
        map.merge(k, 2, (oldVal, newVal) -> oldVal + newVal);

看上面一段代码,我们首先创建了一个HashMap,并往里面放入了一个键值为k:1的元素。当我们调用merge函数,往map里面放入k:2键值对的时候,k键发生重复,就执行后面的lambda表达式。表达式的含义是:返回旧值oldVal加上新值newVal(1+2),现在map里面只有一项元素那就是k:3。

其实lambda表达式很简单:表示匿名函数,箭头左侧是参数,箭头右侧是函数体。函数的参数类型和返回值,由代码上下文来确定。

三、按Map的键排序

下面一个例子使用Java 8 Stream按Map的键进行排序:

// 创建一个Map,并填入数据
Map<String, Integer> codes = new HashMap<>();
codes.put("United States", 1);
codes.put("Germany", 49);
codes.put("France", 33);
codes.put("China", 86);
codes.put("Pakistan", 92);

// 按照Map的键进行排序
Map<String, Integer> sortedMap = codes.entrySet().stream()
        .sorted(Map.Entry.comparingByKey())
        .collect(
                Collectors.toMap(
                    Map.Entry::getKey,
                    Map.Entry::getValue,
                    (oldVal, newVal) -> oldVal,
                    LinkedHashMap::new
                )
        );

// 将排序后的Map打印
sortedMap.entrySet().forEach(System.out::println);

看上文中第二段代码:

  • 首先使用entrySet().stream() 将Map类型转换为Stream流类型。
  • 然后使用sorted方法排序,排序的依据是Map.Entry.comparingByKey(),也就是按照Map的键排序
  • 最后用collect方法将Stream流转成LinkedHashMap。 其他参数都好说,重点看第三个参数,就是一个merge规则的lambda表达式,与merge方法的第三个参数的用法一致。由于本例中没有重复的key,所以新值旧值随便返回一个即可。

上面的程序将在控制台上打印以下内容,键(国家/地区名称)以自然字母顺序排序:

China=86
France=33
Germany=49
Pakistan=92
United States=1

请注意使用LinkedHashMap来存储排序的结果以保持顺序。默认情况下,Collectors.toMap()返回HashMapHashMap不能保证元素的顺序。

如果希望按照键进行逆向排序,加入下图中红色部分代码即可。

四、按Map的值排序

当然,您也可以使用Stream API按其值对Map进行排序:

Map<String, Integer> sortedMap2 = codes.entrySet().stream()
        .sorted(Map.Entry.comparingByValue())
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (oldVal, newVal) -> oldVal,
                LinkedHashMap::new));

sortedMap2.entrySet().forEach(System.out::println);

这是显示Map按值排序的输出:

United States=1
France=33
Germany=49
China=86
Pakistan=92

五、使用TreeMap按键排序

大家可能都知道TreeMap内的元素是有顺序的,所以利用TreeMap排序也是可取的一种方法。您需要做的就是创建一个TreeMap对象,并将数据从HashMapput到TreeMap中,非常简单:

// 将 `HashMap` 转为 `TreeMap`
Map<String, Integer> sorted = new TreeMap<>(codes);

这是输出:

China=86
France=33
Germany=49
Pakistan=92
United States=1

如上所示,键(国家/地区名称)以自然字母顺序排序。

期待您的关注

原文地址:https://www.cnblogs.com/zimug/p/11781375.html

时间: 2024-08-05 15:28:42

使用Java8 Stream API对Map按键或值进行排序的相关文章

Java8 Stream API

Stream是Java8中,操作集合的一个重要特性. 从iteration到Stream操作 当你操作一个集合的时候,你通常的做法是迭代每一个元素,然后处理你想要的事情.举个例子: String contents = new String(Files.readAllBytes( Paths.get("alice.txt")), StandardCharsets.UTF_8); // 读取文件到字符串中 List<String> words = Arrays.asList(c

何用Java8 Stream API进行数据抽取与收集

上一篇中我们通过一个实例看到了Java8 Stream API 相较于传统的的Java 集合操作的简洁与优势,本篇我们依然借助于一个实际的例子来看看Java8 Stream API 如何抽取及收集数据. 备注:上一篇内容:如何用Java8 Stream API找到心仪的女朋友 ## 目标&背景 我们以"处理订单数据"为例,假设我们的应用是一个分布式应用,有"订单应用","物流应用","商品应用"等都是独立的服务.本次我

java8 stream limit distinct map flatMap

对元素为map的list按map中的值进行排序

Collections.sort(list, new Comparator<Map<String, Object>>() { @Override public int compare(Map<String, Object> o1, Map<String, Object> o2) { Integer value1 = 0; Integer value2 = 0; for (String key : o1.keySet()) { value1 = (Intege

JAVA中对list map根据map某个key值进行排序

package test; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; public class java_ListMapSort { public static void main(String[] args) { // TO

java map 根据 map的value值进行排序

1 //根据销量排行查询 2 public void queryGoodsByHotCount(){ 3 //将map集合键和值封装到entry对象中 然后转换成set集合 4 Set<Entry<Integer,Goods>>setGoods=mapGoods.entrySet(); 5 //将set集合转成list集合 6 List<Entry<Integer,Goods>> listGoods=new ArrayList<>(); 7 li

Java中对listmap根据map某个key值进行排序

Collection提供了排序方法sort(),但对于List<Map> 需要根据Map中某一个或某几个Key进行排序,就需要重写sort()方法来实现了: 实现方式如下: public static void main(String[] args) { List<Map<String, String>> list = new ArrayList<Map<String, String>>(); Map<String, String>

Android Map根据键或者值进行排序

在解析JSON数据的时候,就常会解析到JsonObject,而jsonObject是无序的,但是有想让他变的有序,就会在每个JsonObject中加一个属性,sort,然后根据sort值的大小进行排序 这里简化为map根据或值进行排序 1.先往一个map集合里加入键值对 Map<String, Integer> map = new HashMap<String, Integer>(); map.put("文具", 1); map.put("饮料&quo

JAVA8新特性之 Stream API

重要的 Stream API  : java.util.Stream.* Stream提供了一种高效且简易处理数据的方式 注意:1.Stream自己不会存储元素 2.对Stream进行操作不会改变数据源,相反,会产生一个执有结果的新Stream 3.Stream操作是延迟执行的.只有进行了终止操作才会产生结果 (并行流就是把内容分成多个数据块,并用不同的线程分别处理每个数据块.在Java8 后,Stream API可以声明性的通过parallel()与sequential()在并行流与串行流(顺