Java 集合处理:用 record 与 Stream 统计完成任务
用 record 描述任务,通过 Stream 筛选和累计,理解不可修改列表、终结操作和保留原数据的处理方式。
本节目标
用 record 描述任务,通过 Stream 筛选和累计,理解不可修改列表、终结操作和保留原数据的处理方式。
环境与运行方法
准备 JDK 21。保存为 Lesson.java,执行 javac -Xlint:all Lesson.java,再执行 java Lesson。文件名与 public 类名一致,运行时使用类名而不是 .class 文件名。
核心思路
简单任务拥有标题、分钟数和完成状态,record 可以减少数据载体的样板代码。List.of 返回不可修改列表,统计只读取数据,不需要为了计算而改变任务。
完整示例
import java.util.List;
public class Lesson {
record Task(String title, int minutes, boolean done) {}
public static void main(String[] args) {
var tasks = List.of(new Task("read", 20, true),
new Task("practice", 40, false),
new Task("review", 10, true));
int total = tasks.stream().filter(Task::done).mapToInt(Task::minutes).sum();
long count = tasks.stream().filter(Task::done).count();
System.out.println("completed=" + count + " total=" + total);
System.out.println("original=" + tasks.size());
}
}预期输出
completed=2 total=30
original=3逐步理解
filter 保留完成任务,mapToInt 提取分钟数,sum 累计。count 返回 long,而非 int。两次统计分别创建流,因为一个 Stream 完成终结操作后不能再次消费。
record 不保证深度不可变;若成员是可变集合,集合内部仍可能改变。本例成员简单,便于观察。需要追加任务时可创建 ArrayList 副本,同时明确谁有权修改状态。
常见问题与边界
- List.of 不允许 null,也不支持 add。
- 不能反复使用已经消费的 Stream。
- record 不会自动检查负时长或空标题。
动手练习
让所有任务未完成,再使用空 List。
参考答案
两种情况都得到完成数零和总时长零,但第一种原始数量仍为 3,空 List 的原始数量是零。这两类状态在界面上可能需要不同提示。
文章回复
0 条公开回复