一、什么是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

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

期待您的关注

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

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

    上一篇中我们通过一个实例看到了Java8 Stream API 相较于传统的的Java 集合操作的简洁与优势,本篇我们依然借助于一个实际的例子来看看Java8 Stream API 如何抽取及收集数据 ...

  2. 如何用Java8 Stream API找到心仪的女朋友

    传统的的Java 集合操作是有些啰嗦的,当我们需要对结合元素进行过滤,排序等操作的时候,通常需要写好几行代码以及定义临时变量. 而Java8 Stream API 可以极大简化这一操作,代码行数少,且 ...

  3. C++中实现对map按照value值进行排序 - 菜鸟变身记 - 51CTO技术博客

    C++中实现对map按照value值进行排序 - 菜鸟变身记 - 51CTO技术博客 C++中实现对map按照value值进行排序 2012-03-15 15:32:36 标签:map 职场 休闲 排 ...

  4. python中字典按键、值进行排序

    看到排序,就不禁想起python中的sort和sorted sort是列表中的方法,用于对列表进行排序(改变的是原列表,不返回新列表) 用法: list.sort(key=None,reverse=T ...

  5. 恕我直言你可能真的不会java第12篇-如何使用Stream API对Map类型元素排序

    在这篇文章中,您将学习如何使用Java对Map进行排序.前几日有位朋友面试遇到了这个问题,看似很简单的问题,但是如果不仔细研究一下也是很容易让人懵圈的面试题.所以我决定写这样一篇文章.在Java中,有 ...

  6. JAVA8 Stream API的使用

    /** * @auther hhh * @date 2018/12/31 12:48 * @description Stream流:用来处理数组.集合的API * 1.不是数据结构,没有内部存储(只是 ...

  7. Fork/Join框架与Java8 Stream API 之并行流的速度比较

    Fork/Join 框架有特定的ExecutorService和线程池构成.ExecutorService可以运行任务,并且这个任务会被分解成较小的任务,它们从线程池中被fork(被不同的线程执行)出 ...

  8. Java8 Stream API

    Stream是Java8中,操作集合的一个重要特性. 从iteration到Stream操作 当你操作一个集合的时候,你通常的做法是迭代每一个元素,然后处理你想要的事情.举个例子: String co ...

  9. java8 stream api流式编程

    java8自带常用的函数式接口 Predicate boolean test(T t) 传入一个参数返回boolean值 Consumer void accept(T t) 传入一个参数,无返回值 F ...

随机推荐

  1. Scrapy项目 - 实现腾讯网站社会招聘信息爬取的爬虫设计

    通过使Scrapy框架,进行数据挖掘和对web站点页面提取结构化数据,掌握如何使用Twisted异步网络框架来处理网络通讯的问题,可以加快我们的下载速度,也可深入接触各种中间件接口,灵活的完成各种需求 ...

  2. Git项目分支分配

    主要分支包含master分支与develop分支,临时分支可以分为: release: 从develop分出 ,是最终要发布的版本. feature: 实现某功能时推荐新建分支,从develop分出. ...

  3. .Net Core快速创建Windows服务

    1.新建.Net Core控制台程序,添加新建项Windows服务: NuGet引用 System.ServiceProcess.ServiceController,然后修改Progran.cs: c ...

  4. Kafka 学习笔记之 ZooKeeper作用

    Kafka使用ZooKeeper 配置管理 Leader Election 服务发现 首先进入ZooKeeper客户端: ls / 可以看到有以下节点: 查看Topic 配置信息:体现了ZooKeep ...

  5. 【Java基础】让编码不再让你困惑

    目录 1. ASCII编码 2. Unicode编码 3. UTF-8编码 4. UTF8.UTF16和UTF32之间的区别 5. GBK.GB2312和GB18030之间的区别 6. Java中的编 ...

  6. 软件开发工具(第12章: CVS的安装及使用)

    一.CVS介绍 并发版本系统(Concurrent Versions System——CVS)是一个常用 的代码版本控制系统. 使用CVS可以对代码进行集中管理,记录代码所有的更改历史,提供 协作开发 ...

  7. Activity的四种加载模式详解:

    先来看看总结图: 模式详解: standard模式: 标准启动模式,也是activity的默认启动模式.在这种模式下启动的activity可以被多次实例化,即在同一个任务中可以存在多个activity ...

  8. POJ - 2393Yogurt factory

    The cows have purchased a yogurt factory that makes world-famous Yucky Yogurt. Over the next N (1 &l ...

  9. UVa12105 越大越好

    题文:https://vjudge.net/problem/12364(或者见紫书) 题解: 因为题目中有两个限制条件,那么我们就顺着题目的意思来dp,设dp[i][j]表示目前还剩下的i个火柴,用这 ...

  10. zoj 3886 Nico Number

    中文题面: 问题描述] 我们定义一个非负整数是“好数”,当且仅当它符合以下条件之一: 1. 这个数是0或1 2. 所有小于这个数且与它互质的正整数可以排成一个等差数列 例如,8就是一个好数,因为1,3 ...