目录
一、对流中数据进行聚合计算
当我们使用Stream流处理数据后,可以像数据库的聚合函数一样对某个字段进行操作。比如获取最大值,获取最小值,求总和,平均值,统计数量。
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;
}
@Override
public 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流处理数据后,可以根据某个属性将数据分组:
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;
}
@Override
public 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;
}
}
运行输出结果:
三、对流中数据进行多级分组
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;
}
@Override
public 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列表。
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;
}
@Override
public 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 会根据指定的连接符,将所有元素连接成一个字符串。
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;
}
@Override
public 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;
}
}
运行输出结果:
标签:聚合,name,Stream,int,第十一章,age,score,Student,public From: https://blog.csdn.net/qushaming/article/details/143869603