返回顶部
首页 > 资讯 > 后端开发 > Python >一文详解Java中的Stream的汇总和分组操作
  • 923
分享到

一文详解Java中的Stream的汇总和分组操作

2024-04-02 19:04:59 923人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录前言一、查找流中的最大值和最小值二、汇总三、连接字符串四、分组1、分组2、多级分组3、按子组数据进行划分后记前言 在前面的文章中其实大家也已经看到我使用过collect(Coll

前言

在前面的文章中其实大家也已经看到我使用过collect(Collectors.toList()) 将数据最后汇总成一个 List 集合

但其实还可以转换成Integer、Map、Set 集合等。

一、查找流中的最大值和最小值

     static List<Student> students = new ArrayList<>();
 ​
     static {
         students.add(new Student("学生A", "大学A", 18, 98.0));
         students.add(new Student("学生B", "大学A", 18, 91.0));
         students.add(new Student("学生C", "大学A", 18, 90.0));
         students.add(new Student("学生D", "大学B", 18, 76.0));
         students.add(new Student("学生E", "大学B", 18, 91.0));
         students.add(new Student("学生F", "大学B", 19, 65.0));
         students.add(new Student("学生G", "大学C", 20, 80.0));
         students.add(new Student("学生H", "大学C", 21, 78.0));
         students.add(new Student("学生I", "大学C", 20, 67.0));
         students.add(new Student("学生J", "大学D", 22, 87.0));
     }
 ​
     public static void main(String[] args) {
         Optional<Student> collect1 = students.stream().collect(Collectors.maxBy((s1, s2) -> s1.getAge() - s2.getAge()));
         Optional<Student> collect2 = students.stream().collect(Collectors.minBy((s1, s2) -> s1.getAge() - s2.getAge()));
         Student max = collect1.get();
         Student min = collect2.get();
         System.out.println("max年龄的学生==>" + max);
         System.out.println("min年龄的学生==>" + min);
         
     }

Optional,它是一个容器,可以包含也可以不包含值。它是java8中人们常说的优雅的判空的操作。

另一个常见的返回单个值的归约操作是对流中对象的一个数值字段求和。或者你可能想要求 平均数。这种操作被称为汇总操作。让我们来看看如何使用收集器来表达汇总操作。

二、汇总

Collectors类专门为汇总提供了一些个工厂方法:

当然除此之外还有 求平均数averagingDouble、求总数counting等等

我们暂且就先以summingDoublesummarizingDouble来举例吧

案例数据仍然是上面的那些student数据...

求全部学生成绩的总分,求全部学生的平均分。

1、首先使用summingDoubleaveragingDouble 来实现

 Double summingScore = students.stream().collect(Collectors.summingDouble(Student::getScore));
 Double averagingScore = students.stream().collect(Collectors.averagingDouble(Student::getScore));
 System.out.println("学生的总分==>" + summingScore);
 System.out.println("学生的平均分==>" + averagingScore);
 

2、使用summarizingDouble来实现

它更为综合,可以直接计算出相关的汇总信息

 DoubleSummaryStatistics summarizingDouble = students.stream().collect(Collectors.summarizingDouble(Student::getScore));
 ​
 double sum = summarizingDouble.getSum();
 long count = summarizingDouble.getCount();
 double average = summarizingDouble.getAverage();
 double max = summarizingDouble.getMax();
 double min = summarizingDouble.getMin();
 System.out.println("sum==>"+sum);
 System.out.println("count==>"+count);
 System.out.println("average==>"+average);
 System.out.println("max==>"+max);
 System.out.println("min==>"+min);
 

但其实大家也都发现了,使用一个接口能够实现,也可以拆开根据自己的所需,选择合适的api来实现,具体的使用还是需要看使用场景。

三、连接字符串

Joining,就是把流中每一个对象应用toString方法得到的所有字符串连接成一个字符串。

如果这么看,它其实没啥用,但是Java也留下了后招,它的同伴(重载方法)提供了一个可以接受元素之间的分割符的方法。

 ​
         String studentsName = students.stream().map(student -> student.getName()).collect(Collectors.joining());
         System.out.println(studentsName);
         String studentsName2 = students.stream().map(student -> student.getName()).collect(Collectors.joining(","));
         System.out.println(studentsName2);
         

对于对象的打印:

 // 不过对于对象的打印 个人感觉还好 哈哈
 String collect = students.stream().map(student -> student.toString()).collect(Collectors.joining(","));
 System.out.println(collect);
 System.out.println(students);
 

但其实我还有一些没有讲到的API使用方法,大家也可以额外去尝试尝试,这其实远比你看这篇文章吸收的更快~

四、分组

就像数据库中的分组统计一样~

1、分组

举个例子,我想统计每个学校有哪些学生

我是不是得设计这样的一个数据结构Map<String,List<Student>>才能存放勒,我在循环的时候,是不是每次都得判断一下学生所在的学校的名称,然后看是否要给它添加到这个List集合中去,最后再put到map中去呢?

看着就特别繁琐,但是在 stream 中就变成了一行代码,其他的东西,都是 Java 内部给你优化了

         // 我想知道每所学校中,学生的数量及相关信息,只要这一行代码即可
         Map<String, List<Student>> collect = students.stream().collect(Collectors.groupingBy(Student::getSchool));
         System.out.println(collect);
         

有些时候这真的是十分有用且方便的

但是有时候我们往往不止于如此,假如我要统计每个学校中20岁年龄以上和20以下的学生分别有哪些学生,那么我的参数就不再是Student::getSchool了,而是要加上语句了。那么该如何编写呢

 //统计每个学校中20岁年龄以上和20以下的学生分别有多少
 Map<String, List<Student>> collect = students.stream().collect(Collectors.groupingBy(student -> {
     if (student.getAge() > 20) {
         return "20岁以上的";
     }
     return "20以下的";
 }));
 System.out.println(collect);

如果要统计每个学校有多少20岁以上和20岁以下的学生的信息,其实也就是把 return 语句修改以下即可。

 //统计每个学校中20岁年龄以上和20以下的学生分别有多少
 Map<String, List<Student>> collect = students.stream().collect(Collectors.groupingBy(student -> {
     if (student.getAge() > 20) {
         return student.getSchool();
     }
     return student.getSchool();
 }));
 System.out.println(collect);

相信大家也看出来groupingBy中的 return 语句就是 Map 中的key值

2、多级分组

但其实groupingBy()并不只是一个人,它也有兄弟姐妹

假如我想把上面的例子再改造改造,

改为:我想知道20岁以上的学生在每个学校有哪些学生,20岁以下的学生在每个学校有哪些学生。

数据结构就应当设计为Map<String, Map<String, List<Student>>> 啦,第一级存放 20岁以上以下两组数据,第二级存放以每个学校名为key的数据信息。

 Map<String, Map<String, List<Student>>> collect = students.stream().collect(Collectors.groupingBy(Student::getSchool, Collectors.groupingBy(student -> {
     if (student.getAge() > 20) {
         return "20以上的";
     }
     return "20岁以下的";
 })));
 System.out.println(collect);
 

这里利用的就是把一个内层groupingBy传递给外层groupingBy,俗称的套娃~

外层Map的键就是第一级分类函数生成的值,而这个Map的值又是一个Map,键是二级分类函数生成的值。

3、按子组数据进行划分

之前我的截图中,groupingBy的重载方法中,其实对于第二个参数的限制,并非说一定是要groupingBy类型的收集,更抽象点说,它可以是任意的收集器~

再假如,我的例子改为:

我现在明确的想知道每个学校20岁的学生的人数。

那么这个数据结构就应当改为

Map<String,Long>或者是Map<String,Integer>呢?

那么在这里该如何实现呢?

 Map<String, Long> collect = students.stream().collect(Collectors.groupingBy(Student::getSchool, Collectors.counting()));
 System.out.println(collect);
 

实际上还有许多未曾谈到的东西,这里都只是非常简单的应用,对于其中的流的执行的先后顺序,以及一些简单的原理,都没有过多的涉及,大家先上手用着吧~

后记

我这里只是阐述了一些比较简单的应用性操作,未谈及设计思想之类,但是要明白那种才是更值得去阅读和理解的。

到此这篇关于一文详解Java中的Stream的汇总和分组操作的文章就介绍到这了,更多相关Java Stream汇总 分组内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 一文详解Java中的Stream的汇总和分组操作

本文链接: https://lsjlt.com/news/166511.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 一文详解Java中的Stream的汇总和分组操作
    目录前言一、查找流中的最大值和最小值二、汇总三、连接字符串四、分组1、分组2、多级分组3、按子组数据进行划分后记前言 在前面的文章中其实大家也已经看到我使用过collect(Coll...
    99+
    2024-04-02
  • Stream流中的groupingBy分组操作
     code: //根据医院编号,查询医院所有科室信息 Department departmentQuery = new Department(); departmentQuery.setHoscode(hoscode); Example ...
    99+
    2023-09-01
    java mysql sql
  • 一文详解Java中Stream流的使用
    目录简介操作1:创建流操作2:中间操作筛选(过滤)、去重映射排序消费操作3:终止操作匹配、最值、个数收集规约简介 说明 本文用实例介绍stream的使用。 JDK8新增了Stream...
    99+
    2024-04-02
  • Nodejs文件操作和stream的示例分析
    小编给大家分享一下Nodejs文件操作和stream的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!NodeJS文件操作...
    99+
    2024-04-02
  • Java Stream流的常见生成和操作方法总结
    目录一、Stream流简单示例二、Stream流常见生成方式三、Stream流中间操作方法filter代码示例limit&skip代码示例concat&distinc...
    99+
    2024-04-02
  • 一文详解Golang中的位操作
    本篇文章带大家深入了解下Golang中的位操作,介绍一下详述每个操作符以及它们如何使用的案例,希望对大家有所帮助!php零基础到就业直播视频课:进入学习全程直播 + 实战授课 + 边学 + 边练 + 边辅导【推荐】《接口如何自动化测试?单流...
    99+
    2024-04-02
  • 一文详解Java中字符串的基本操作
    目录一、遍历字符串案例二、统计字符次数案例三、字符串拼接案例四、字符串反转案例五、帮助文档查看String常用方法一、遍历字符串案例 需求:键盘录入一个字符串,使用程序实现在控制台遍...
    99+
    2024-04-02
  • 一文详解Golang中的替换操作
    在现代编程领域中,Golang (又称Go语言) 始终保持着高度的增长和流行度。Golang 作为一门新兴的编程语言,以其简单高效、轻量快速的特性成为了很多开发者的首选。最近,Golang 中的一系列替换操作引起了广泛的讨论和探讨。在这篇文...
    99+
    2023-05-14
  • java 流操作对文件的分割和合并的实例详解
    java 流操作对文件的分割和合并的实例详解学习文件的输入输出流,自己做一个小的示例,对文件进行分割和合并。    下面是代码:package com.dufy.file; import java.io.Fi...
    99+
    2023-05-31
    java 分割合并 作对
  • 一文详解DOM的概念和常用操作
    目录DOM 的概念和常用操作什么是 DOM如何操作 DOM一些常用的 HTML DOM 方法:核心就是增删改查操作,一些常用的 HTML DOM 属性DOM 的概念和常用操作 什么是...
    99+
    2023-05-17
    DOM概念 DOM常用操作
  • 从零开始学习Java中的Shell脚本:数组和文件操作详解!
    在Java中,Shell脚本是一种非常重要的编程方式,它可以让我们更加方便地完成一些基本的操作。在本文中,我们将会深入讲解如何在Java中使用Shell脚本完成数组和文件操作。 一、数组操作 在Java中,数组操作是非常常见的。我们可以使...
    99+
    2023-10-31
    shell 数组 文件
  • Java中Stream流中map和forEach的区别详解
    目录什么是 stream 流MapforEach使用场景不是很难的知识,但是今天犯错了,记录一下 什么是 stream 流 我们在使用集合或数组对元素进行操作时往往会遇到这种情况:通...
    99+
    2024-04-02
  • 详解Python中的文件操作
    1.能调用方法的一定是对象,比如数值、字符串、列表、元组、字典,甚至文件也是对象,Python中一切皆为对象。 str1 = 'hello' str2 = 'world' str3 = ' '.j...
    99+
    2022-06-04
    详解 操作 文件
  • java数组的初始化及操作详解
    Java数组的初始化及操作详解:数组的初始化是指在创建数组对象时为数组元素赋予初值。Java数组的初始化有以下几种方式:1. 静态初...
    99+
    2023-08-17
    Java
  • PythonNumpy中数组的集合操作详解
    我们知道两个 set 对象之间,可以取交集、并集、差集、对称差集,举个例子: s1 = {1, 2, 3} s2 = {2, 3, 4} """ &: 交集 |: 并集  ...
    99+
    2024-04-02
  • MySQL分区表和分桶表的操作详解
    目录1.创建分区表2.增删改查操作2.1 插入数据2.2 操作数据3. 二级分区表3.1 创建分区表3.2 插入数据4.动态分区5.分桶表5.1 新建分桶表5.2 插入数据5.3 既分区有分桶6 分区与分桶的区别1.创建...
    99+
    2023-05-12
    MySQL分区表和分桶表 MySQL分区表 MySQL分桶表
  • MongoDB中的push操作详解(将文档插入到数组)
    目录1. 概述2. 数据库初始化3. 使用 Mongo Query 进行推送操作4. 使用Java驱动代码进行推送操作4.1. 使用 DBObject4.2. 使用 BSON 文档5. 使用 addToSet操作符5.1...
    99+
    2024-04-02
  • 一文了解axios和vue的整合操作
    目录前言一、axios是什么?1.定义2.原理3、主要特点二、axios的应用三、axios+vue的应用总结前言 前面学习了vue的本地应用操作,本文将会学习Vue的网络应用,介绍...
    99+
    2024-04-02
  • Python中的元组(Tuple)操作实例详解
    目录引言1.元组的 创建 && 访问(1)元组的创建:(2)访问:2.元组的 修改 && 删除(1)元组的修改:(2)元组的删除:3.元组的内置方法4...
    99+
    2024-04-02
  • Java中Properties类的操作实例详解
    Java中Properties类的操作实例详解知识学而不用,就等于没用,到真正用到的时候还得重新再学。最近在看几款开源模拟器的源码,里面涉及到了很多关于Properties类的引用,由于Java已经好久没用了,而这些模拟器大多用Java来写...
    99+
    2023-05-31
    java properties
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作