本文目录导读:

- 案例1:学生成绩筛选与排序
- 案例2:订单金额统计(映射与归约)
- 案例3:分组统计(计数、平均值)
- 案例4:字符串处理(flatMap)
- 案例5:简单并行计算(parallelStream)
- 总结:Stream API常见操作一览
案例1:学生成绩筛选与排序
需求:有一个学生列表,找出成绩大于80分的女生,并按成绩降序排列,只取前3名。
import java.util.*;
import java.util.stream.*;
class Student {
String name;
String gender;
int score;
public Student(String name, String gender, int score) {
this.name = name;
this.gender = gender;
this.score = score;
}
public String toString() {
return name + "(" + gender + ", " + score + ")";
}
}
public class StreamDemo1 {
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student("Alice", "female", 85),
new Student("Bob", "male", 78),
new Student("Cathy", "female", 92),
new Student("David", "male", 88),
new Student("Eva", "female", 79),
new Student("Frank", "male", 95)
);
List<Student> result = students.stream()
.filter(s -> s.gender.equals("female"))
.filter(s -> s.score > 80)
.sorted((a, b) -> Integer.compare(b.score, a.score))
.limit(3)
.collect(Collectors.toList());
result.forEach(System.out::println);
// 输出: Cathy(female, 92) Alice(female, 85)
// 注:只有2个满足条件,limit(3)不会报错
}
}
关键Stream操作:filter → sorted → limit → collect
案例2:订单金额统计(映射与归约)
需求:计算所有已支付订单的总金额,并将每个订单的金额增加10%后输出。
import java.util.*;
import java.util.stream.*;
class Order {
int id;
String status;
double amount;
public Order(int id, String status, double amount) {
this.id = id;
this.status = status;
this.amount = amount;
}
}
public class StreamDemo2 {
public static void main(String[] args) {
List<Order> orders = Arrays.asList(
new Order(1, "paid", 100.0),
new Order(2, "unpaid", 50.0),
new Order(3, "paid", 200.0),
new Order(4, "paid", 150.0),
new Order(5, "cancelled", 30.0)
);
// 1. 筛选已支付,映射出金额,加10%,再求和
double total = orders.stream()
.filter(o -> "paid".equals(o.status))
.mapToDouble(o -> o.amount * 1.1)
.sum();
System.out.println("总金额(含10%加成): " + total); // 100*1.1 + 200*1.1 + 150*1.1 = 495.0
// 2. 如果想得到每个加成后的金额列表
List<Double> amountsAfterIncrease = orders.stream()
.filter(o -> "paid".equals(o.status))
.map(o -> o.amount * 1.1)
.collect(Collectors.toList());
System.out.println("各订单金额: " + amountsAfterIncrease);
}
}
关键Stream操作:filter → mapToDouble / map → sum / collect
案例3:分组统计(计数、平均值)
需求:将员工按部门分组,统计每个部门的人数,并计算每个部门的平均薪资。
import java.util.*;
import java.util.stream.*;
class Employee {
String name;
String department;
double salary;
public Employee(String name, String department, double salary) {
this.name = name;
this.department = department;
this.salary = salary;
}
}
public class StreamDemo3 {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("Tom", "IT", 8000),
new Employee("Jerry", "IT", 9500),
new Employee("Alice", "HR", 6500),
new Employee("Bob", "HR", 7200),
new Employee("Charlie", "Sales", 9000),
new Employee("Diana", "Sales", 11000)
);
// 按部门分组,统计人数
Map<String, Long> deptCount = employees.stream()
.collect(Collectors.groupingBy(e -> e.department, Collectors.counting()));
System.out.println("各部门人数: " + deptCount);
// 按部门分组,计算平均薪资
Map<String, Double> avgSalaryByDept = employees.stream()
.collect(Collectors.groupingBy(
e -> e.department,
Collectors.averagingDouble(e -> e.salary)
));
System.out.println("各部门平均薪资: " + avgSalaryByDept);
// 按部门分组,并列出所有员工姓名
Map<String, List<String>> namesByDept = employees.stream()
.collect(Collectors.groupingBy(
e -> e.department,
Collectors.mapping(e -> e.name, Collectors.toList())
));
System.out.println("各部门员工姓名: " + namesByDept);
}
}
关键Stream操作:collect + groupingBy(配合下游收集器 counting、averagingDouble、mapping)
案例4:字符串处理(flatMap)
需求:给定一个句子列表,将每个句子拆分成单词,去重后按字母顺序排序输出。
import java.util.*;
import java.util.stream.*;
public class StreamDemo4 {
public static void main(String[] args) {
List<String> sentences = Arrays.asList(
"Java is powerful",
"Stream API is elegant",
"Functional programming is fun"
);
List<String> distinctSortedWords = sentences.stream()
.flatMap(sentence -> Arrays.stream(sentence.split(" ")))
.map(String::toLowerCase)
.distinct()
.sorted()
.collect(Collectors.toList());
System.out.println(distinctSortedWords);
// 输出: [api, elegant, fun, functional, is, java, powerful, programming, stream]
}
}
关键Stream操作:flatMap(将多个流合并为一个) → distinct → sorted
案例5:简单并行计算(parallelStream)
需求:对1到1000000的整数求和,使用并行流提高性能。
import java.util.stream.LongStream;
public class StreamDemo5 {
public static void main(String[] args) {
long sum = LongStream.rangeClosed(1, 1_000_000)
.parallel()
.sum();
System.out.println("1到1,000,000的和: " + sum);
// 输出: 500000500000
}
}
关键Stream操作:parallel(将串行流转为并行流,适用于CPU密集、无状态操作)
Stream API常见操作一览
| 操作类别 | 方法示例 | 用途 |
|---|---|---|
| 创建流 | stream()、parallelStream()、Stream.of() |
从集合/数组/值生成流 |
| 中间操作 | filter、map、flatMap、distinct、sorted、limit、skip |
对数据进行转换与筛选 |
| 终端操作 | collect、forEach、count、reduce、anyMatch、allMatch、findFirst、min、max |
触发计算并产生结果 |
| 收集器 | Collectors.toList()、groupingBy、partitioningBy、joining、summarizingDouble |
将流元素收集到容器或进行统计 |
这些案例基本覆盖了工作中最常见的Stream使用模式,建议你在实际编码中多加练习,特别是 map、filter 和 collect 的组合使用。