Java 8 Collectors to Map
1. 介绍
在本教程中,我们将讨论Collectors类的toMap()方法。我们使用它将流收集到一个Map实例中。
对于本教程中涉及的所有示例,我们将使用图书列表作为数据源,并将其转换为不同的Map实现。
2. List 转换 Map
我们将从最简单的情况开始,将List 转换 Map。
Book类定义如下:
class Book {
private String name;
private int releaseYear;
private String isbn;
//getters and setters
}
复制代码
接着,我们将创建一个List<Book>来验证我们的代码:
List<Book> bookList = new ArrayList<>();
bookList.add(new Book("The Fellowship of the Ring", 1954, "0395489318"));
bookList.add(new Book("The Two Towers", 1954, "0345339711"));
bookList.add(new Book("The Return of the King", 1955, "0618129111"));
复制代码
对于这个场景,我们将使用以下重载的toMap()方法:
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper)
复制代码
使用Collectors.toMap(), 我们将会得到一个Map<String,String>,其中key是isbn的值,value为name的值。
public Map<String, String> listToMap(List<Book> books) {
return books.stream().collect(Collectors.toMap(Book::getIsbn, Book::getName));
}
复制代码
我们使用单元测试来验证一下代码:
@Test
public void whenConvertFromListToMap() {
assertTrue(convertToMap.listToMap(bookList).size() == 3);//true
}
复制代码
3. 解决 Key 的冲突
上面的例子运行得很好,但是如果有一个重复的key会发生什么呢?
让我们来想象一下,我们将每本图书的出版年份作为key,转换到Map<Integer, Book>中。
public Map<Integer, Book> listToMapWithDupKeyError(List<Book> books) {
return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity()));
}
复制代码
鉴于我们上面的例子,我们会看到一个IllegalStateException的异常:
@Test(expected = IllegalStateException.class)
public void whenMapHasDuplicateKey_without_merge_function_then_runtime_exception() {
convertToMap.listToMapWithDupKeyError(bookList);
}
复制代码
要解决这个问题,我们需要使用另一种toMap()方法,附加一个参数,mergeFunction:
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
复制代码
让我们引入一个merge函数,它表明,在发生冲突的情况下,我们保留现有的元素:
public Map<Integer, Book> listToMapWithDupKey(List<Book> books) {
return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(),
(existing, replacement) -> existing));
}
复制代码
或者,换句话说,我们获得了未发生异常的元素:
@Test
public void whenMapHasDuplicateKeyThenMergeFunctionHandlesCollision() {
Map<Integer, Book> booksByYear = convertToMap.listToMapWithDupKey(bookList);
assertEquals(2, booksByYear.size());
assertEquals("0395489318", booksByYear.get(1954).getIsbn());
}
复制代码
4. 其他Map类型
默认情况下,toMap()方法将返回一个HashMap。 但是我们也可以返回不同的Map实现。
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier)
复制代码
其中mapSupplier是一个函数,它返回一个新的、带有结果的空Map。
4.1. List 转换 ConcurrentMap
让我们以上面的例子为例,添加一个mapSupplier函数来返回一个ConcurrentHashMap:
public Map<Integer, Book> listToConcurrentMap(List<Book> books) {
return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(),
(o1, o2) -> o1, ConcurrentHashMap::new));
}
复制代码
下面我们测试一下
@Test
public void whenCreateConcurrentHashMap() {
assertTrue(convertToMap.listToConcurrentMap(bookList) instanceof ConcurrentHashMap);
}
复制代码
4.2. List 转换 SortedMap
最后,让我们看看如何返回一个排序后的Map。为此,我们需要对List<Book>进行排序,并使用TreeMap作为mapSupplier参数:
public TreeMap<String, Book> listToSortedMap(List<Book> books) {
return books.stream()
.sorted(Comparator.comparing(Book::getName))
.collect(Collectors.toMap(Book::getName, Function.identity(), (o1, o2) -> o1, TreeMap::new));
}
复制代码
上面的代码将List<Book>按照书名进行排序,然后将结果收集到TreeMap<String, Book>中:
@Test
public void whenMapisSorted() {
assertTrue(convertToMap.listToSortedMap(bookList).firstKey().equals("The Fellowship of the Ring"));
}
复制代码
5. 结论
在本文中,我们研究了Collectors类的toMap()方法。它允许我们从一个流创建一个新的Map。我们还学习了如何解决key冲突和创建不同的Map实现。
代码可以在GitHub中找到。
作者:Rodrigo Graciano
译者:李东
作者:锅外的大佬
链接:https://juejin.im/post/5d06f11b5188252a71629c7b
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Java 8 Collectors to Map的更多相关文章
- Java 8 – Filter a Map examples
Java 8 – Filter a Map examplesFew Java examples to show you how to filter a Map with Java 8 stream A ...
- Java集合框架之map
Java集合框架之map. Map的主要实现类有HashMap,LinkedHashMap,TreeMap,等等.具体可参阅API文档. 其中HashMap是无序排序. LinkedHashMap是自 ...
- Java中如何遍历Map对象的4种方法
在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都实现了Map接口,以下方法适用于任何map实现(HashMap, TreeMap, LinkedHa ...
- JAVA的容器---List,Map,Set (转)
JAVA的容器---List,Map,Set Collection├List│├LinkedList│├ArrayList│└Vector│ └Stack└SetMap├Hashtable├HashM ...
- 转!! Java中如何遍历Map对象的4种方法
在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都 ...
- Java 集合系列 15 Map总结
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 08 Map架构
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- 【转】Java中如何遍历Map对
在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都 ...
- 【转】Java中如何遍历Map对象的4种方法
原文网址:http://blog.csdn.net/tjcyjd/article/details/11111401 在Java中如何遍历Map对象 How to Iterate Over a Map ...
随机推荐
- 更新yum 源
CentOS系统自带的更新源的速度实在是慢,为了让CentOS6使用速度更快的YUM更新源,可以选择163(网易)的更新源. 1.下载repo文件 wget http://mirrors.163.co ...
- Java Class 与 Object
平时看代码时,总是碰到这些即熟悉又陌生的名次,每天都与他们相见,但见面后又似曾没有任何的交集,所以今天我就来认识下这两个江湖侠客的背景: CLASS 在Java中,每个class都有一个相应的Clas ...
- bzoj 1367 - sequence
Description 给定一个序列\(t_1,t_2,\cdots,t_n\),求一个递增序列\(z_1<z_2<...<z_n\), 使得 \(R=|t_1−z_1|+|t_2− ...
- 海拔(bzoj 2007)
Description YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个 正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1) ...
- HDOJ Important Sisters
Important Sisters Time Limit: 7000/7000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- 鼠标放在预览图a.gif上,旁边有放大图出现
原文发布时间为:2009-04-23 -- 来源于本人的百度文章 [由搬家工具导入] <html><script type="text/javascript"&g ...
- 【Android】SQLite基本用法(转)
在Android开发中SQLite起着很重要的作用,网上SQLite的教程有很多很多,不过那些教程大多数都讲得不是很全面.本人总结了一些SQLite的常用的方法,借着论坛的大赛,跟大家分享分享的.一. ...
- 修改手機的 input source 及 charger 及 usb 相關電路後,容易忽略的事項
input source 及 charger 需要注意, 是否可以在關機的狀況下充電, 當然 開機充電 是一定要的. usb 部分需要注意, 是否可以在沒有電或者是有電的狀況下 download 程式 ...
- Bioconda安装与使用
1. Bioconda是一个自动化管理生物信息软件的工具,就像APPstore.360软件管家一样. Bioconda的优点是安装简单,各个软件依赖的环境一同打包且相互隔离,非常适合在服务器中建立自 ...
- qemu相关命令使用
qemu-ga qemu-guest-agent-2.5.0-3.el7.x86_64 qemu-img qemu-img-1.5.3-105.el7_2.4.x86_64 qemu-io qemu- ...