【Java基础】Stream 流中 Collectors.toMap 的用法

这篇具有很好参考价值的文章主要介绍了【Java基础】Stream 流中 Collectors.toMap 的用法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Collectors.toMap 方法使用技巧

Collectors.toMap() 方法是把 List 转 Map 的操作

二、代码案例

1、demo案例

public static void main(String[] args) {
    List<Student> list = Arrays.asList(
        new Student(1, "张三", 20, "29.8"),
        new Student(2, "李四", 25, "29.5"),
        new Student(3, "赵武", 23, "30.8"),
        new Student(4, "王六", 22, "31.8")
    );
    
    list 打印输出为:[
                Student(id=1, name=张三, age=20, score=29.8), 
                Student(id=2, name=李四, age=25, score=29.5), 
                Student(id=3, name=赵武, age=23, score=30.8), 
                Student(id=4, name=王六, age=22, score=31.8)
               ]

    /**
     * id 作为 map 的key,name 作为 value
     * 结果集: {1=张三, 2=李四, 3=赵武, 4=王六}
    */
    Map<Integer, String> collect = list.stream()
        .collect(Collectors.toMap(Student::getId, Student::getName));
    System.out.println(collect);

    /**
     * id 作为 map 的 key,Student 对象作为 map 的 value
     * 结果集: {1=Student(id=1, name=张三, age=20, score=29.8), 
                2=Student(id=2, name=李四, age=25, score=29.5), 
                3=Student(id=3, name=赵武, age=23, score=30.8),
                4=Student(id=4, name=王六, age=22, score=31.8)}
    */
    Map<Integer, Student> collect1 = list.stream()
        .collect(Collectors.toMap(Student::getId, v -> v));
    System.out.println(collect1);

    /**
     * id 作为 map 的 key,Student 对象作为 map 的 value
     * 结果集: {1=Student(id=1, name=张三, age=20, score=29.8),
                2=Student(id=2, name=李四, age=25, score=29.5), 
                3=Student(id=3, name=赵武, age=23, score=30.8), 
                4=Student(id=4, name=王六, age=22, score=31.8)}
     */
    Map<Integer, Student> collect2 = list.stream()
        .collect(Collectors.toMap(Student::getId, Function.identity()));
    System.out.println(collect2);
}

1.1、如果不是对象,是数组,怎么转成map?

String typeBanner = "A=1,B=2,C=3";
String[] typeBannerArray = typeBanner.split(",");
System.out.println(Arrays.toString(typeBannerArray));  // [A=1, B=2, C=3]
Map<String, String> typeBannerMap = Arrays.stream(typeBannerArray).collect(Collectors.toMap(
                (array) -> array.split("=")[0],
                (array) -> array.split("=")[1]
        ));
System.out.println(typeBannerMap);  // {A=1, B=2, C=3}

2、当 map 上述 id 如果重复,会报主键重复异常,解决办法:

按照规范来写的话,最好所有toMap,都要将这个异常提前考虑进去,不然有时候会报重复主键异常,这也是正例的写法,上面的属于反例的写法。

2.1、Collectors.toMap 有三个重载方法: 

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);

参数解释:

1. keyMapperKey 的映射函数,Student:getId 表示选择 Student 的 getId 作为 map 的 key 值。

2. valueMapperValue的映射函数,Function.identity() 表示选择将原来的对象作为 Map 的value 值。

3. mergeFunction:当 Key 冲突时,调用的合并方法。(n1,n2)->n1 中,如果 n1 与 n2 的 key 值相同,选择 n1 作为那个 key 所对应的 value 值。

4. mapSupplierMap 构造器,在需要返回特定的 Map 时使用。第四个参数 mapSupplier 用于返回一个任意类型的 Map 实例,比如我们希望返回的 Map 是根据 Key 排序的。TreeMap::new

public static void main(String[] args) {
    List<Student> list = Arrays.asList(
        new Student(1, "张三", 20, "29.8"),
        new Student(2, "李四", 25, "29.5"),
        new Student(1, "赵武", 23, "30.8"),
        new Student(4, "王六", 22, "31.8")
    );
    /**
     * id 作为 map 的key,重复 id 的 name 合并作为 value
     * 结果集: {1=张三,赵武, 2=李四, 4=王六}
    */
    Map<Integer, String> collect = list.stream()
        .collect(Collectors.toMap(Student::getId, Student::getName, (n1, n2) -> n1 +","+ n2));
    System.out.println(collect);

    /**
     * 取前面一个 Student 对象
     * 结果集: {1=Student(id=1, name=张三, age=20, score=29.8), 
                2=Student(id=2, name=李四, age=25, score=29.5), 
                4=Student(id=4, name=王六, age=22, score=31.8)}
    */
    Map<Integer, Student> collect1 = list.stream()
        .collect(Collectors.toMap(Student::getId, Function.identity(), (n1, n2) -> n1));
    System.out.println(collect1);

    /**
     * 取后面一个 Student 对象
     * 结果集: {1=Student(id=1, name=赵武, age=23, score=30.8),
                2=Student(id=2, name=李四, age=25, score=29.5), 
                4=Student(id=4, name=王六, age=22, score=31.8)}
     */
    Map<Integer, Student> collect2 = list.stream()
        .collect(Collectors.toMap(Student::getId, Function.identity(), (n1, n2) -> n2, TreeMap::new));
    System.out.println(collect2);
}

 写案例遇到的问题有,上述第一个输出,如果写成 n1 + n2 ,map 第二个参数类型是对象或者是list集合,都是显示编译报错状态。文章来源地址https://www.toymoban.com/news/detail-631392.html

到了这里,关于【Java基础】Stream 流中 Collectors.toMap 的用法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java stream流toMap使用过程中空指针问题

    Java8中stream操作list时常见的一个错误: 排查原因: 定位到代码中发现从数据查询是存在数据的 排查stream前对象为null的情况,那问题只能出现在toMap这里了 我们需要知道toMap是怎么帮我们封装数据的,先搞明白toMap的原理,点击源码可以看到他并不是通过map中的put方法封装数

    2024年02月05日
    浏览(27)
  • JAVA07_Stream流中FindFirst方法查找元素第一个

    ①. Stream的findFirst方法在此流中查找第一个元素作为Optional,如果流中没有元素,findFirst返回空的Optional,如果findFirst选择的元素为null,它将抛出NullPointerException Optional findFirst() ②. findAny():返回流中的任意一个元素;如果流是空的,则返回空 对于串行流,输出的都是查找第一个元素 对于

    2024年02月12日
    浏览(30)
  • Java解决stream流Collectors.groupingBy 分组统计可能报空指针异常

    在使用stream流的Collectors.groupingBy做分组统计时(示例代码如下) 如果统计的字段userName有null值则会报如下错误 解决方法为在统计之前增加一个filter方法将null值事先过滤掉。代码如下:

    2024年02月04日
    浏览(30)
  • java8新特性Stream流中anyMatch和allMatch和noneMatch的使用!!!

    判断数据列表中是否存在任意一个元素符合设置的predicate条件,如果是就返回true,否则返回false。 接口定义: boolean anyMatch(Predicate? super T predicate); 方法描述: 在anyMatch 接口定义中是接收 Predicate 类型参数,在Lamdba表达式中 PredicateT 是接收一个T类型参数,然后经过逻辑验证返

    2024年02月08日
    浏览(42)
  • Java Stream 处理分组后取每组最大&Stream流之list转map、分组取每组第一条&Java 8 Collectors:reducing 示例(List分组取最值)

    有一个需求功能:先按照某一字段分组,再按照另外字段获取最大的那个 先根据appId分组,然后根据versionSort取最大. JDK1.8推出的stream流能极大的简化对集合的操作,让代码更美观,老规矩,直接上代码。 取list中对象的某个属性作为唯一key,对象作为value形成一个map集合,能

    2024年02月16日
    浏览(44)
  • java stream中的peek()用法

    最近看到一段代码: 之前没有用过peek,于是查了一下,peek的作用是: 改变元素的内部状态 从这句话中可以看出,上面代码的意思是:对每个 object 执行 saveInfomation(object, params) ,然后把结果收集到一个 List 里。 这里涉及到了 最终操作 。 peek() 并不是一个最终操作(termina

    2024年02月08日
    浏览(33)
  • Java Stream 最全操作用法合集

    Java 8 引入了Stream流的操作,让我们在开发的过程中感受到了很多的便利,小宋我也花时间总结了下关于Stream的堪称最全的使用方法,话不多说,直接放大招。 Java 8提供了两种方式去创建流: 1、stream stream是串行的,可以理解为它的执行是 按顺序执行 的。 2、parallelStream par

    2024年02月16日
    浏览(32)
  • Java中stream流的常见用法

    这篇文章主要是记录stream流的用法,因为stream流比较常用,并且一些操作较复杂,记录在此,以后参考。 1、filter用法 主要是用来过滤集合中的元素,较常用。 2、peek用法 主要是用来修改元素的状态,比如其中对象的字段等 3、map用法 主要是用来替换集合中的元素 4、flatma

    2024年02月12日
    浏览(47)
  • 详细解决java中的Collectors.toMap引起的java.lang.IllegalStateException: Duplicate key xxx 的错误

    今天,测试在禅道上给我指出一个正式环境 bug ,如下图所示: 即 java.lang.IllegalStateException: Duplicate key 2 。 根据 java.lang.IllegalStateException: Duplicate key 2 可知,这是 java 抛出的存在 2个重复键 的错误。 如果想要弄清楚错误原因,通过如下几个步骤分析: 首先,看到这个错误信息

    2024年01月19日
    浏览(43)
  • Java8中Stream详细用法大全

    Java 8 是一个非常成功的版本,这个版本新增的Stream,配合同版本出现的Lambda ,给我们操作集合(Collection)提供了极大的便利。Stream流是JDK8新增的成员,允许以声明性方式处理数据集合,可以把Stream流看作是遍历数据集合的一个高级迭代器。Stream 是 Java8 中处理集合的关键抽

    2023年04月08日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包