Stream ToMap(Collectors.toMap) 实践_Oxygen的博客-程序员宝宝_collectors.tomap

技术标签: Java  java  Stream  

Requirements

List TO Map
List Stream 转换 Map时向collect()方法中传递Collector对象,对象由Collectors.toMap()方法返回。

如下实现List转换为Map

List<GroupBrandCateBO> list = new ArrayList<>(
      Arrays.asList(
              new GroupBrandCateBO("v1", "g1", "b1"),
              new GroupBrandCateBO("v1", "g1", "b1"),
              new GroupBrandCateBO("v3", "g3", "b3")
      )
);
Map<String, String> map = list.stream().collect(Collectors.toMap(item -> item.getVersion(), item -> item.getGroupCode(), (oldVal, currVal) -> oldVal, LinkedHashMap::new)); 
System.out.println(map.getClass());
Map<String, String> map0 = list.stream().collect(Collectors.toMap(item -> item.getVersion(), item -> item.getGroupCode(), (oldVal, currVal) -> oldVal));
System.out.println(map0.getClass());
System.out.println(map0.toString());
Map<String, String> map1 = list.stream().collect(Collectors.toMap(GroupBrandCateBO::getVersion, GroupBrandCateBO::getGroupCode));
System.out.println(map1.toString());

Console
class java.util.LinkedHashMap
class java.util.HashMap
{v1=g1, v3=g3}
Exception in thread “main” java.lang.IllegalStateException: Duplicate key g1
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)

问题分析

toMap()函数重载:
未指定合并函数mergeFunction情况下,传入throwingMerger()返回BinaryOperator对象,当出现key重复时,调用合并函数!
未指定Supplier实例情况下,默认生成HashMap实例。

public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper) {
    return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}

public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper,
                                BinaryOperator<U> mergeFunction) {
    return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}

public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
                            Function<? super T, ? extends U> valueMapper,
                            BinaryOperator<U> mergeFunction,
                            Supplier<M> mapSupplier) {
    BiConsumer<M, T> accumulator
            = (map, element) -> map.merge(keyMapper.apply(element),
                                          valueMapper.apply(element), mergeFunction);
    return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}

private static <T> BinaryOperator<T> throwingMerger() {
    return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
}

补充

关于合并函数

List<GroupBrandCateBO> list = new ArrayList<>(
       Arrays.asList(
               new GroupBrandCateBO("v1", "g1", "b1"),
               new GroupBrandCateBO("v1", "g2", "b2"),
               new GroupBrandCateBO("v1", "g2", "b2"),
               new GroupBrandCateBO("v3", "g3", "b3")
       )
);
Map<String, String> map00 = list.stream().collect(Collectors.toMap(item -> item.getVersion(), item -> item.getGroupCode(), (oldVal, currVal) -> currVal));
Map<String, String> map01 = list.stream().collect(Collectors.toMap(item -> item.getVersion(), item -> item.getGroupCode(), (oldVal, currVal) -> oldVal + currVal));
System.out.println(map00.toString());
System.out.println(map01.toString());

Console
{v1=g2, v3=g3}
{v1=g1g2g2, v3=g3}

传入Lambda表达式将转化为BinaryOperator<U> mergeFunction对象,合并处理value,非Key!!!
比如:

(oldVal, currVal) -> currVal) // key相同时当前值替换原始值
(oldVal, currVal) -> oldVal + currVal //key相同时保留原始值和当前值
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xiaolulululululu/article/details/86636203

智能推荐

ThumbnailUtils的使用_Jack-Chan的博客-程序员宝宝

特别喜欢系统中一些小而精的工具类,有的时候分析一下别有一番味道。ThumbnailUtils是系统内置的一个生成缩略图的工具类,只有512行代码,网上有很多使用ThumbnailUtils的例子,刚好我个人正在整理Bitmap的相关资料,希望从中也能有所收获。

C语言中的set jmp()和long jmp()_Aiden御舟的博客-程序员宝宝_c语言jmp

与刺激的abort()和exit()相比,goto语句看起来是处理异常的更可行方案。不幸的是,goto是本地的:它只能跳到所在函数内部的标号上,而不能将控制权转移到所在程序的任意地点(当然,除非你的所有代码都在main体中)。  为了解决这个限制,C函数库提供了setjmp()和longjmp()函数,它们分别承担非局部标号和goto作用。头文件申明了这些函数及同时所需的jmp_buf

ncnn源码分析1_一名小菜鸟的学习之路的博客-程序员宝宝_ncnn源码分析

&nbsp; &nbsp; &nbsp; &nbsp; 前段时间,分别尝试了使用腾讯开源的深度学习推理框架ncnn、陈天奇大神团队开源的tvm,及最新的阿里开源mnn,就好用程度来说,腾讯的n...

跟着鸟哥学Linux系列笔记1_weixin_30448603的博客-程序员宝宝

跟着鸟哥学Linux系列笔记0-扫盲之概念跟着鸟哥学Linux系列笔记0-如何解决问题装完linux之后,接下来一步就是进行相关命令的学习了第五章:首次登录与在线求助man page1. X Window切换至命令行模式:  Ctrl + Alt + F1~F6: 文字界面登录 tty1~tty6终端;  Ctrl + Alt + F7: 图形界面桌面2. ...

2.5.3 创建子弹;2.5.4创建子弹Prefab;2.5.5发射子弹;2.6 创建敌人;2.7.1 添加碰撞体_taotaoahui的博客-程序员宝宝

using UnityEngine;using System.Collections;//[AddComponentMenu("MyGame/Rocket")]public class Rocket : MonoBehaviour { // 子弹飞行速度 public float m_speed = 10; // 生存事件 public float m

我读 《国富论》 - 亚当 · 斯密 / 论增进劳动生产力的因素,以及劳动生产物在各个阶层中自然分配的顺序_简简单单OnlineZuozuo的博客-程序员宝宝

文章目录我读 《国富论》 - 亚当 · 斯密 / 论增进劳动生产力的因素,以及劳动生产物在各个阶层中自然分配的顺序1、论工资2、国家工资3、对婚姻影响我读 《国富论》 - 亚当 · 斯密 / 论增进劳动生产力的因素,以及劳动生产物在各个阶层中自然分配的顺序1、论工资分工引发的各种改良会促使劳动生产力提高,劳动工资也会随之增长。可是所有的生产物品却呈现越来越廉价的趋势,原因就在于,他们所需要付出的劳动少了。各种商品是在劳动等量的情况下进行彼此交换的。无论在哪里, 对劳动者的普通工资起决定作用的都是

随便推点

Android进阶之路①:五大布局_老天子的博客-程序员宝宝

Android进阶之路①:五大布局Android进阶之路①:五大布局LinearLayout 线性布局常用属性视图RelativeLayout常用属性视图TableLayout常用属性视图FramLayout视图AbsoluteLayout常用属性视图本文总结Android界面之:Android五大布局LinearLayou...

flashback database 方法_congxinlan3332的博客-程序员宝宝

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Jan 23 23:30:17 2010Copyright (c) 1982, 2007, Oracle. All...

mozjpeg:JPEG图片压缩5%,获Facebook支持_weixin_33889665的博客-程序员宝宝

mozjpeg是一个来自Mozilla实验室的JPEG图像编码器项目,目标是在不降低图像质量且兼容主流的解码器的情况下,提供产品级的JPEG格式编码器来提高压缩率以减小JPEG文件的大小。Mozilla指出,这些年来,网站的图片使用数量和大小都在与日俱增,而HTML、JS和CSS文件大小都相对减小了。也就是说在页面加载的过程中,图片占用了大量的网络流量...

uboot-2015-07的start.S的文件启动过程_shenlong1356的博客-程序员宝宝

https://blog.csdn.net/u013904227/article/details/51648179https://www.cnblogs.com/debruyne/p/9208809.htmlhttps://blog.csdn.net/weixin_41734376/article/details/98586549

数据结构之通用树结构的实现_顾小豆的博客-程序员宝宝_树结构实现

之前我们讲了树的定义和操作,这节我们讲一下如何实现这些操作。既然要考虑如何实现,那就得说说树的存储结构。大家都知道树是非线性数据结构,显然我们无法用数组来表示树的逻辑结构。那我们应该怎么办呢?通过什么来表示呢?其实可以设计结构体数组对结点间的关系进行表述。如下图所示:从上图发现,将根结点的双亲定义为-1,表示其没有双亲;将根的孩子结点的双亲定义为0,表示其双亲是根结点;将根结点孩子1的孩子结点的双...