第十一章 对Stream流的聚合函数处理

devtools/2024/11/19 9:00:04/

目录

一、对流中数据进行聚合计算

二、对流中数据进行分组

三、对流中数据进行多级分组

四、对流中数据进行分区 

4.1. 使用方式及代码

4.2. 分区于分组的区别

分区(Partitioning)

分组(Grouping)

实际应用场景

五、对流中数据进行拼接


一、对流中数据进行聚合计算

当我们使用Stream流处理数据后,可以像数据库的聚合函数一样对某个字段进行操作。比如获取最大值,获取最小值,求总和,平均值,统计数量。

java">package com.wzx;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class Test {public static void main(String[] args) {Stream<Student> studentStream = Stream.of(new Student("赵丽颖", 58, 95),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 99),new Student("柳岩", 52, 77));// 获取最大值Optional<Student> collect1 = studentStream.collect(Collectors.maxBy((o1, o2) ->o1.getScore() - o2.getScore()));System.out.println(collect1.get());// 获取最小值Optional<Student> collect2 = studentStream.collect(Collectors.minBy((o1, o2) ->o1.getScore() - o2.getScore()));System.out.println(collect2.get());// 求总和int sumAge = studentStream.collect(Collectors.summingInt(s -> s.getAge()));System.out.println("sumAge = " + sumAge);// 平均值double avgScore = studentStream.collect(Collectors.averagingInt(s -> s.getScore()));System.out.println("avgScore = " + avgScore);// 统计数量Long count = studentStream.collect(Collectors.counting());System.out.println("count = " + count);}
}class Student {private String name;private int age;private int score;public Student() {}public Student(String name, int age, int score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}
}

二、对流中数据进行分组

当我们使用Stream流处理数据后,可以根据某个属性将数据分组:

java">package com.wzx;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class Test {public static void main(String[] args) {Stream<Student> studentStream1 = Stream.of(new Student("赵丽颖", 52, 95),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 55),new Student("柳岩", 52, 33));Map<Integer, List<Student>> map1 = studentStream1.collect(Collectors.groupingBy(Student::getAge));map1.forEach((k, v) -> {System.out.println(k + "::" + v);});Stream<Student> studentStream2 = Stream.of(new Student("赵丽颖", 52, 95),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 55),new Student("柳岩", 52, 33));// 将分数大于60的分为一组,小于60分成另一组Map<String, List<Student>> map2 = studentStream2.collect(Collectors.groupingBy((s) ->{if (s.getScore() > 60) {return "及格";} else {return "不及格";}}));map2.forEach((k, v) -> {System.out.println(k + "::" + v);});}
}class Student {private String name;private int age;private int score;public Student() {}public Student(String name, int age, int score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}
}

运行输出结果:

三、对流中数据进行多级分组

java">package com.wzx;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class Test {public static void main(String[] args) {Stream<Student> studentStream = Stream.of(new Student("赵丽颖", 52, 95),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 99),new Student("柳岩", 52, 77));Map<Integer, Map<String, List<Student>>> map =studentStream.collect(Collectors.groupingBy(s -> s.getAge(), Collectors.groupingBy(s -> {if (s.getScore() >= 90) {return "优秀";} else if (s.getScore() >= 80 && s.getScore() < 90) {return "良好";} else if (s.getScore() >= 80 && s.getScore() < 80) {return "及格";} else {return "不及格";}})));map.forEach((k, v) -> {System.out.println(k + " == " + v);});}
}class Student {private String name;private int age;private int score;public Student() {}public Student(String name, int age, int score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}
}

运行输出效果:

四、对流中数据进行分区 

4.1. 使用方式及代码

Collectors.partitioningBy 会根据值是否为true,把集合分割为两个列表,一个true列表,一个false列表。

java">package com.wzx;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class Test {public static void main(String[] args) {Stream<Student> studentStream = Stream.of(new Student("赵丽颖", 52, 95),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 99),new Student("柳岩", 52, 77));// partitioningBy会根据值是否为true,把集合分割为两个列表,一个true列表,一个false列表。Map<Boolean, List<Student>> map = studentStream.collect(Collectors.partitioningBy(s ->s.getScore() > 90));map.forEach((k, v) -> {System.out.println(k + " == " + v);});}
}class Student {private String name;private int age;private int score;public Student() {}public Student(String name, int age, int score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}
}

运行输出结果,可以明显看到分区输出结果是一个数组:

4.2. 分区于分组的区别

Stream流的分区和分组是两种不同的操作,它们在数据处理上有明显的区别。

分区(Partitioning)

分区操作是将流中的元素根据某个条件分成两个或多个子流。分区操作的结果是一个流,而不是一个集合。例如,可以使用分区操作将学生按照分数高低分成两个子流:高分和低分。分区操作通常使用partitioningBy方法实现,该方法返回一个Map,其中键是分区条件,值是对应的流‌1。

分组(Grouping)

分组操作是将流中的元素按照某个分类函数分成不同的组。分组操作的结果是一个Map,其中键是分类函数返回的值,值是具有该分类值的元素的列表。例如,可以使用分组操作将交易记录按照货币类型分成不同的组,每组包含所有相同货币类型的交易记录‌1。分组操作通常使用groupingBy方法实现。

实际应用场景

  • 分区‌:适用于需要将数据分成两个或多个子集进行进一步处理的场景。例如,将学生按照分数高低分成两个子流,然后对每个子流进行不同的处理。
  • 分组‌:适用于需要将数据按照某个属性进行分类汇总的场景。例如,将交易记录按照货币类型分组,以便进行统计和分析。

五、对流中数据进行拼接

Collectors.joining 会根据指定的连接符,将所有元素连接成一个字符串。

java">package com.wzx;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class Test {public static void main(String[] args) {Stream<Student> studentStream = Stream.of(new Student("赵丽颖", 52, 95),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 99),new Student("柳岩", 52, 77));String collect = studentStream.map(Student::getName).collect(Collectors.joining(">_<", "^_^", "^v^"));System.out.println(collect);}
}class Student {private String name;private int age;private int score;public Student() {}public Student(String name, int age, int score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}
}

运行输出结果:

 


http://www.ppmy.cn/devtools/135167.html

相关文章

20-大模型外挂知识库优化——负样本样本挖掘篇

大模型外挂知识库优化——负样本样本挖掘篇 一、为什么需要构建负难样本&#xff1f; 在各类检索任务中&#xff0c;为训练好一个高质量的检索模型&#xff0c;往往需要从大量的候选样本集合中采样高质量的负例&#xff0c;配合正例一起进行训练。 二、负难样本构建方法篇 …

WIFI-TTL透传模块说明书

WIFI-TTL透传模块说明书 V 1.0 2022-11-24 目录 1 简介... 4 2 模块参数... 4 3 接口定义... 5 4 设备配网... 6 5 AT指令... 11 6 恢复出厂... 12 7 设备配置... 13 7.1 配置界面说明... 13 7.2 TTL串口配置... 13 7.3 …

【Patroni官方文档】FAQ

FAQ&#xff08;常见问题解答&#xff09; 在本节中&#xff0c;您将找到关于Patroni的最常见问题的答案。每个小节都试图关注不同类型的问题。 我们希望这能帮助您澄清大部分问题。如果您仍然有进一步的疑虑或遇到意外问题&#xff0c;请参考“聊天和报告错误”部分&#xf…

交易术语汇总(Technical Trading Dictionary)

Arbitrage (套利) --- 一种利用交易所之间的差价获利的方法。 Accumulation (累积) --- 在一种资产中建立头寸的过程。 Ask/Bid (询价/竞价) --- 卖出订单是询价(Ask)&#xff0c;买入订单是出价(Bid)。 ATH&#xff08;历史最高价) --- All-time high 全时高。 Bearish MS…

c++20模块示例

模块接口声明&#xff0c;MyModule.cppm&#xff1a; export module MyModule; export namespace MyNamespace {void printHello(); }模块实现&#xff0c;MyModuleImpl.cpp&#xff1a; module;#include <iostream>module MyModule; namespace MyNamespace {void prin…

最简单的设计模式,抽象工厂模式,是否属于过度设计?

目录 一、不采用抽象工厂模式1、抽象产品2、具体产品3、测试类 ~ 不用抽象工厂模式4、新增笔记本的CPU和内存5、在Client测试类中新增&#xff1a; 二、那么&#xff0c;如果采用抽象工厂模式优化上面代码&#xff0c;要怎么做呢&#xff1f;抽象工厂模式通常包括以下几个部分&…

etcd defrag

场景 prometheus监控告警,告警信息如下 etcd cluster "kube-etcd": database size in use on instance xx is 33.45% of the actual allocated disk space, please run defragmentation (e.g. etcdctl defrag) to retrieve the unused fragmented disk space.处理…

【大语言模型】ACL2024论文-15 大型语言模型中的最佳解释推断

【大语言模型】ACL2024论文-15 大型语言模型中的最佳解释推断 目录 文章目录 【大语言模型】ACL2024论文-15 大型语言模型中的最佳解释推断目录摘要研究背景问题与挑战如何解决创新点算法模型实验效果推荐阅读指数&#xff1a;★★★★☆后记 大型语言模型中的最佳解释推断 摘…