Java8 Collectors to Map
专注分享国外最新技术内容
1. 介绍
在本教程中,我们将讨论
Collectors
类的 toMap()
方法。我们使用它将流收集到一个 Map
实例中。对于本教程中涉及的所有示例,我们将使用图书列表作为数据源,并将其转换为不同的
Map
实现。2. List 转换 Map
我们将从最简单的情况开始,将
List
转换 Map
。Book
类定义如下:classBook{
privateString name;
privateint releaseYear;
privateString isbn;
//getters and setters
}
接着,我们将创建一个
List<Book>
来验证我们的代码:List<Book> bookList =newArrayList<>();
bookList.add(newBook("The Fellowship of the Ring",1954,"0395489318"));
bookList.add(newBook("The Two Towers",1954,"0345339711"));
bookList.add(newBook("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的值。publicMap<String,String> listToMap(List<Book> books){
return books.stream().collect(Collectors.toMap(Book::getIsbn,Book::getName));
}
我们使用单元测试来验证一下代码:
@Test
publicvoid whenConvertFromListToMap(){
assertTrue(convertToMap.listToMap(bookList).size()==3);//true
}
3. 解决 Key 的冲突
上面的例子运行得很好,但是如果有一个重复的key会发生什么呢?
让我们来想象一下,我们将每本图书的出版年份作为key,转换到
Map<Integer,Book>
中。publicMap<Integer,Book> listToMapWithDupKeyError(List<Book> books){
return books.stream().collect(Collectors.toMap(Book::getReleaseYear,Function.identity()));
}
鉴于我们上面的例子,我们会看到一个
IllegalStateException
的异常:@Test(expected =IllegalStateException.class)
publicvoid 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函数,它表明,在发生冲突的情况下,我们保留现有的元素:
publicMap<Integer,Book> listToMapWithDupKey(List<Book> books){
return books.stream().collect(Collectors.toMap(Book::getReleaseYear,Function.identity(),
(existing, replacement)-> existing));
}
或者,换句话说,我们获得了未发生异常的元素:
@Test
publicvoid 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
:publicMap<Integer,Book> listToConcurrentMap(List<Book> books){
return books.stream().collect(Collectors.toMap(Book::getReleaseYear,Function.identity(),
(o1, o2)-> o1,ConcurrentHashMap::new));
}
下面我们测试一下
@Test
publicvoid whenCreateConcurrentHashMap(){
assertTrue(convertToMap.listToConcurrentMap(bookList)instanceofConcurrentHashMap);
}
4.2. List 转换 SortedMap
最后,让我们看看如何返回一个排序后的Map。为此,我们需要对
List<Book>
进行排序,并使用 TreeMap
作为mapSupplier参数:publicTreeMap<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
publicvoid whenMapisSorted(){
assertTrue(convertToMap.listToSortedMap(bookList).firstKey().equals("The Fellowship of the Ring"));
}
5. 结论
在本文中,我们研究了
Collectors
类的 toMap()
方法。它允许我们从一个流创建一个新的 Map
。我们还学习了如何解决key冲突和创建不同的 Map
实现。代码可以在GitHub中找到。
原文链接:https://www.baeldung.com/java-collectors-tomap作者:Rodrigo Graciano译者:李东
推荐阅读:
上篇好文:
文章对你是否有帮助呢?
别忘记点右上角按钮分享给更多人哦~
点击在看,和我一起帮助更多开发者!
阅读原文 最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。