我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java Stream 处理分组后取每组最大&Stream流之list转map、分组取每组第一条&Java 8 Collectors:reducing 示例(List分组取最值)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java Stream 处理分组后取每组最大&Stream流之list转map、分组取每组第一条&Java 8 Collectors:reducing 示例(List分组取最值)

Java Stream 处理分组后取每组最大

有一个需求功能:先按照某一字段分组,再按照另外字段获取最大的那个

Map<String, HitRuleConfig> configMap = configList.parallelStream().collect(               Collectors.groupingBy(HitRuleConfig::getAppId, // 先根据appId分组               Collectors.collectingAndThen(               Collectors.reducing(( c1,  c2) -> c1.getVersionSort() > c2.getVersionSort() ? c1 : c2), Optional::get)));

先根据appId分组,然后根据versionSort取最大.

【编程技巧】Stream流之list转map、分组取每组第一条

前言

JDK1.8推出的stream流能极大的简化对集合的操作,让代码更美观,老规矩,直接上代码。

一、list转map

取list中对象的某个属性作为唯一key,对象作为value形成一个map集合,能够便于在后续业务中取值而不用遍历list集合,使代码更优雅。

代码如下(示例):

public class StreamSkill {    public static void main(String[] args) {        List<TestData> list = new ArrayList<>();        TestData.TestDataBuilder builder = TestData.builder();        builder.id(1).name("老王").age(50).address("隔壁");        list.add(builder.build());        builder.id(2).name("司马老贼").age(45).address("许昌");        list.add(builder.build());        System.out.println(list);        Map<Integer, TestData> map = list.stream().collect(Collectors.toMap(TestData::getId, Function.identity()));        System.out.println(map.get(1));    }}@Data@Builderclass TestData{    private Integer id;    private String name;    private Integer age;    private String address;}

运行结果:
在这里插入图片描述

二、分组取每组第一条数据

通过分组取每组第一条数据的操作可以在很多场景适用,比如取多条数据中最新的一条数据等场景。

代码如下(示例):

public class StreamSkill {    public static void main(String[] args) {        List<TestData> list = new ArrayList<>();        TestData.TestDataBuilder builder = TestData.builder();        builder.id(1).name("老王").age(50).address("隔壁");        list.add(builder.build());        builder.id(2).name("司马老贼").age(45).address("许昌");        list.add(builder.build());        builder.id(3).name("曹贼").age(43).address("许昌");        list.add(builder.build());        builder.id(4).name("大耳朵").age(52).address("益州");        list.add(builder.build());        builder.id(5).name("燕人").age(58).address("益州");        list.add(builder.build());        System.out.println(list);        Map<String, TestData> map = list.stream().collect(                Collectors.groupingBy(TestData::getAddress, Collectors.collectingAndThen(                        Collectors.reducing((t1, t2) -> t1.getAge() > t2.getAge() ? t1 : t2),                        Optional::get                ))        );        System.out.println(map);    }}@Data@Builderclass TestData{    private Integer id;    private String name;    private Integer age;    private String address;}

运行结果:
在这里插入图片描述
从运行结果可以看出,根据address分组后取每组年龄最大的对象信息仅需要
小小的几行代码就可以搞定

总结

实际业务中根据业务合理利用stream流能够很大程度的简化代码,但是这种写法在出现bug的时候排查较为复杂,建议不要在使用stream流的时候在其中写太复杂的逻辑。

Java 8 Collectors:reducing 示例(List分组取最值)

简介

Java 8 Collectors.reducing 利用Comparator(比较器)BinaryOperator(二元运算符)进行减少流中的元素。
Collectors.reducing返回带有Optional数据的Collector(收集器)

Collectors.reducingJava Doc 的方法语法如下。

public static <T> Collector<T,?,Optional<T>> reducing(BinaryOperator<T> op) 

Collectors.reducing返回一个Optional类的收集器。

我们需要传递BinaryOperator(二元运算符)BinaryOperator.maxByBinaryOperator.minBy方法。

BinaryOperator(二元运算符)Comparator(比较器)作为参数。

根据该Comparator(比较器)BinaryOperator(二元运算符),流元素被减少,最后可以作为一个组来收集。

使用场景

Collectors.reducing 主要用于取List列表中的某一类型中的最大或最小的一个元素,例如下列代码,取出各个班级中年龄最大的学生信息。

注:如果最值相同,取列表顺序最先出现的一个。

代码示例

Student.java

package com.concretepage.util;public class Student {    private String name;    private Integer age;    private String className;    public Student(String name,Integer age, String className){        this.name=name;        this.age=age;        this.className = className;    }    public String getName() {        return name;    }    public Integer getAge() {        return age;    }    public String getClassName() {        return className;    }}  

ReducingDemo.java

package com.concretepage.util;import java.util.Arrays;import java.util.Comparator;import java.util.List;import java.util.Map;import java.util.Optional;import java.util.function.BinaryOperator;import java.util.stream.Collectors;public class ReducingDemo {    public static void main(String[] args) {        Student s1 = new Student("Shyam", 22,"A");        Student s2 = new Student("Ram",23,"A");        Student s3 = new Student("Mohan",22,"B");        Student s4 = new Student(null,21,"B");        List<Student> list = Arrays.asList(s1,s2,s3,s4);        Comparator<Student> ageComparator = Comparator.comparing(Student::getAge);         Map<String, Optional<Student>> eldestByClass = list.stream().collect(Collectors.groupingBy(Student::getClassName,                 Collectors.reducing(BinaryOperator.maxBy(ageComparator))));        eldestByClass.forEach((k,v)->System.out.println("Class:"+k+" Age:"+                ((Optional<Student>)v).get().getAge()+" Name:"+((Optional<Student>)v).get().getName()));    }} 

输出

Class:A Age:23 Name:RamClass:B Age:22 Name:Mohan 

来源地址:https://blog.csdn.net/qq_43842093/article/details/130211627

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java Stream 处理分组后取每组最大&Stream流之list转map、分组取每组第一条&Java 8 Collectors:reducing 示例(List分组取最值)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录