文章目录

  • ①. Collectors.toMap介绍
  • ②. Collectors.toMap有三个重载方法
  • ③. 收集一下属性和对象本身
  • ④. 常见的java.lang.IllegalStateException: Duplicate key问题处理

①. Collectors.toMap介绍

  • ①. 在项目开发过程中,我们会将List转为Map拿到特定的数据进行处理

  • ②. 一般来说,转为Map的key尽量保持唯一

public class CollectionToMapDemo {public static void main(String[] args) {House house = new House(1,1,"aa","北京海淀");House house1 = new House(2,2,"bb","湖北武汉");House house2 = new House(3,3,"cc","浙江杭州");List<House> houses = Lists.newArrayList();houses.add(house);houses.add(house1);houses.add(house2);//在实际项目中我们经常会用到 List 转 Map 操作 ->过去是for循环的操作,现在可以学习如下的方法Collectors.toMap/*** 我们收集一下集合中每个对象的两个单独的属性*/Map<String, String> mapHouse = houses.stream().collect(Collectors.toMap(House::getHouseName, House::getAddress));System.out.println(mapHouse);//{cc=浙江杭州, bb=湖北武汉, aa=北京海淀}/*** 前后的属性的数据类型要对应  一般时间业务中收集带有唯一表示的业务数据*/Map<Integer, String> map = houses.stream().collect(Collectors.toMap(House::getOwnerId, House::getHouseName));System.out.println(map);//{1=aa, 2=bb, 3=cc}/*** 收集一下属性和对象本身*/Map<Integer, House> houseMap = houses.stream().collect(Collectors.toMap(House::getOwnerId, o -> o));Map<Integer, House> houseMap1 = houses.stream().collect(Collectors.toMap(House::getOwnerId,  Function.identity()));System.out.println(houseMap);/**{1=House(id=1, ownerId=1, houseName=aa, address=北京海淀),2=House(id=2, ownerId=2, houseName=bb, address=湖北武汉),3=House(id=3, ownerId=3, houseName=cc, address=浙江杭州)}*///业务场景:一般会根据具体的键值 取具体的对象System.out.println(houseMap.get(1));//House(id=1, ownerId=1, houseName=aa, address=北京海淀)//此处的效果同houseMapSystem.out.println(houseMap1);/**{1=House(id=1, ownerId=1, houseName=aa, address=北京海淀),2=House(id=2, ownerId=2, houseName=bb, address=湖北武汉),3=House(id=3, ownerId=3, houseName=cc, address=浙江杭州)}*/}
}
@Data
@AllArgsConstructor
class House {private Integer id;        //idprivate Integer ownerId;   //家主编号private String houseName;  //家庭名称private String address;    //家庭地址
}

②. Collectors.toMap有三个重载方法

  • ①. Collectors.toMap有三个重载方法:
  1. keyMapper:Key 的映射函数
  2. valueMapper:Value 的映射函数
  3. mergeFunction:当 Key 冲突时,调用的合并方法
  4. mapSupplier:Map 构造器,在需要返回特定的 Map 时使用
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,BinaryOperator<U> mergeFunction);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier);
  • ②. 第一个默认生成HashMap:如果key冲突了,会默认抛出异常
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);}
  • ③. 第二个默认生成也是一个HashMap:如果key冲突了,可以按照指定的要求进行合并或者取其任意一个
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);}
  • ④. 第三个可以自定义异常方法和Map类型:
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);}
  • ⑤. 如解决toMap()乱序:使用LinkedHashMap
public class CollectionToMapDemo {public static void main(String[] args) {House house = new House(1,1,"aa","北京海淀");House house1 = new House(2,2,"bb","湖北武汉");House house2 = new House(3,3,"cc","浙江杭州");List<House> houses = Lists.newArrayList();houses.add(house);houses.add(house2);houses.add(house1);/*** 收集一下属性和对象本身*/Map<Integer, House> houseMap = houses.stream().collect(Collectors.toMap(House::getOwnerId, o -> o));System.out.println(houseMap);/**{1=House(id=1, ownerId=1, houseName=aa, address=北京海淀),2=House(id=2, ownerId=2, houseName=bb, address=湖北武汉),3=House(id=3, ownerId=3, houseName=cc, address=浙江杭州)}*/LinkedHashMap<Integer, House> collect = houses.stream().collect(Collectors.toMap(House::getOwnerId, Function.identity(), (v1, v2) -> v1, LinkedHashMap::new));//会按照添加顺序进行处理System.out.println(collect);/**{1=House(id=1, ownerId=1, houseName=aa, address=北京海淀), 3=House(id=3, ownerId=3, houseName=cc, address=浙江杭州), 2=House(id=2, ownerId=2, houseName=bb, address=湖北武汉)}*/}
}
@Data
@AllArgsConstructor
class House {private Integer id;        //idprivate Integer ownerId;   //家主编号private String houseName;  //家庭名称private String address;    //家庭地址
}

③. 收集一下属性和对象本身

houses.stream().collect(Collectors.toMap(House::getOwnerId, o -> o));
// 如果key相同了,这种方式会抛出异常
houses.stream().collect(Collectors.toMap(House::getOwnerId,  Function.identity()));
// 如果key相同了,可以按照指定规则处理
houses.stream().collect(Collectors.toMap(House::getOwnerId,  Function.identity(),(v1,v2)->v1));
        List<User>userList=new ArrayList<>();userList.add(new User(1,"a"));userList.add(new User(2,"b"));userList.add(new User(3,"c"));userList.add(new User(4,"取前者的值"));userList.add(new User(4,"取后者的值"));userList.add(new User(5,"e"));/**如果key中有值重复,取前者(这里打印的是 4:取前者的值)1====User(id=1, name=a)2====User(id=2, name=b)3====User(id=3, name=c)4====User(id=4, name=取前者的值)5====User(id=5, name=e)*///Map<Integer, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, k1 -> k1, (K1, K2) -> K1));/**如果key中有值重复,取后者(这里打印的是 4:取后者的值)1====User(id=1, name=a)2====User(id=2, name=b)3====User(id=3, name=c)4====User(id=4, name=取后者的值)5====User(id=5, name=e)*/Map<Integer, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(), (K1, K2) -> K2));for (Integer key:userMap.keySet()){System.out.println(key+"===="+userMap.get(key));}

④. 常见的java.lang.IllegalStateException: Duplicate key问题处理

  • ①. 修改数据,两个一样的key
     House house = new House(1,1,"aa","北京海淀");House house1 = new House(2,2,"bb","湖北武汉");House house2 = new House(3,3,"cc","浙江杭州");House house3 = new House(3,3,"cc","浙江杭州");List<House> houses = Lists.newArrayList();houses.add(house);houses.add(house1);houses.add(house2);houses.add(house3);/*** 收集一下属性和对象本身*/Map<Integer, House> houseMap = houses.stream().collect(Collectors.toMap(House::getOwnerId, o -> o));System.out.println(houseMap);
  • ②. 线上业务代码出现Duplicate Key的异常,影响了业务逻辑,查看抛出异常部分的代码
Exception in thread "main" java.lang.IllegalStateException: Duplicate key House(id=3, ownerId=3, houseName=cc, address=浙江杭州)at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)at java.util.HashMap.merge(HashMap.java:1253)at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)at com.xiaozhi.collection.CollectionToMapDemo.main(CollectionToMapDemo.java:29)
Process finished with exit code 1
  • ③. 解决办法:出现重复时,取前面value的值,或者取后面放入的value值,则覆盖先前的value值
houses.stream().collect(Collectors.toMap(House::getOwnerId, House::getHousename,(v1,v2)->v2));
houses.stream().collect(Collectors.toMap(House::getOwnerId, House::getHousename,(v1,v2)->v1));
  • ④. 对于结果的操作还有很多处理方法,如拼接等
houses.stream().collect(Collectors.toMap(House::getOwnerId, House::getHousename,(v1,v2)->v1+v2));
具体的实践根据具体的业务来操作数据即可

JAVA集合05_Collection.toMap()应用、三个重载方法、解决重复key问题相关推荐

  1. 深入java并发包源码(三)AQS独占方法源码分析

    深入java并发包源码(一)简介 深入java并发包源码(二)AQS的介绍与使用 深入java并发包源码(三)AQS独占方法源码分析 AQS 的实现原理 学完用 AQS 自定义一个锁以后,我们可以来看 ...

  2. Java集合框架系列教程三:Collection接口

    翻译自:The Collection Interface 一个集合表示一组对象.Collection接口被用来传递对象的集合,具有最强的通用性.例如,默认所有的集合实现都有一个构造器带有一个Colle ...

  3. JAVA集合1(Collection接口,iterator()方法,增强型for循环)

    JAVA集合框架概述 集合框架涉及到的api List接口是继承Collection接口,Set接口是继承Collection接口, ArrayList 类是一个可以动态修改的数组,与普通数组的区别就 ...

  4. java集合之——List的三种遍历方式

    一.使用 iterator(迭代器)遍历 1) java iterrator用于遍历集合,本身并不存放对象. 2)迭代器iterator的基本操作: iterator.hasNext():判断集合中是 ...

  5. Java集合工具类(三)-泛型集合工具类,用于便捷快速的定义、操作集合。包含Set的交集、并集......

    为什么80%的码农都做不了架构师?>>>    /**      * 用该方法来代替 { @code new LinkedList<E>()} 方式获得新的 { @cod ...

  6. Java里阻塞线程的三种实现方法

    在日常开发中,我们有时会遇到遇到多线程处理任务的情况,JDK里提供了便利的 ThreadPoolExecutor以及其包装的工具类Executors.但是我们知道 ExecutorService.ex ...

  7. java字符串是否相等的三种判断方法

    1. == 比较的是否是同一对象 eg:String str1="abc",str2="abc" : if(str1==str2){} 结果为true 因为在j ...

  8. java集合总结_Java中集合总结

    Java数组的长度是固定的,为了使程序能够方便地存储和操作数目不固定的一组数据,JDK类库提供了Java集合,这些集合类都位于java.util包中,但是与数组不同的是,集合中不能存放基本类型数据,而 ...

  9. 关于java集合的知识点_java中集合的知识点

    1.JAVA中集合都存放在java.util包中 2.JAVA集合中主要分为三种类型:Set,List,Map.我写的这篇文章主要是对Set和List的理解 3.Collection是最基本的集合接口 ...

最新文章

  1. NSDate获取当前时区的时间
  2. 什么是重载or重写,二者的区别是?
  3. pyqt5讲解2:QPushButton,QRadioButton,QCheckBox
  4. POJ 2337 欧拉回路
  5. CSS3总结(干货)
  6. 阿里AI再出神器,“你是什么垃圾”一拍便知
  7. linux mplayer_移植mplayer播放器到EK200开发板的步骤浅析
  8. C语言字母的压缩,C语言字符串快速压缩算法代码
  9. 代理设置。 安卓工作室配置用http代理。gradle可能需要这些http代理设置去访问互联网。例如下载依赖。 你想要复制ide的代理配置到这个项目的gradle属性文件吗?...
  10. WPF特效-实现3D足球效果
  11. Pointer Networks简介及其应用(格式化)
  12. 《机器学习实战》总结篇
  13. 贾俊平统计学思维导图- 第二章 数据搜集
  14. 翡翠手链更能够突显佩戴者的非凡气质
  15. Android 源代码在线查看 目录结构 不完全指南
  16. R语言--for循环语句的使用
  17. background:rgba()
  18. 【华为OD机试真题 python】完美走位【2022 Q4 | 100分】
  19. 【Java多数据源实现教程】实现动态数据源、多数据源切换方式
  20. oracle 创建 permanent tablespace

热门文章

  1. 为什么看P1dB压缩,而不是2dB,3dB压缩
  2. visual studio进入时许可证已过期解决方案
  3. 运营技巧|要如何提升用户留存率?
  4. 计算机图形学Bezier曲线试题,《计算机图形学》试题-C卷及参考答案
  5. python中的while语句
  6. C# 重写(override)
  7. x265探索与研究(一):x265下载安装与配置
  8. 归一化互相关(NCC)及其部分应用场景
  9. 计算机二级c语言考试总结,计算机二级考试C语言知识点总结 .doc
  10. 【LaTeX】MikTex+TexStudio安装及配置论文写作环境