分离SideType=0.5和1的数据
for循环
java
// 3. 分离SideType=0.5和1的数据
List<SlaughterWeigh> needMergeList = new ArrayList<>();
List<SlaughterWeigh> normalList = new ArrayList<>();
for (SlaughterWeigh record : originalList) {
if ("0.5".equals(record.getSideType())) {
needMergeList.add(record);
} else {
normalList.add(record);
}
}
Stream 流方案
方案 1:使用 Collectors.partitioningBy(推荐)
java
Map<Boolean, List<SlaughterWeigh>> partitioned = originalList.stream()
.collect(Collectors.partitioningBy(r -> "0.5".equals(r.getSideType())));
List<SlaughterWeigh> needMergeList = partitioned.get(true); // 边口类型 0.5
List<SlaughterWeigh> normalList = partitioned.get(false); // 其他
特点:
- 专为二分类设计(true/false)
- 底层优化,使用
Partition对象,内存效率高 - 不会返回 null,空分组返回空列表
[] - 只能分两组,不能扩展
输出结构:
Map<Boolean, List<SlaughterWeigh>>
├── true → [记录1(0.5), 记录3(0.5), ...] // needMergeList
└── false → [记录2(1), 记录4(null), ...] // normalList
方案 2:使用 Collectors.groupingBy
java
Map<String, List<SlaughterWeigh>> grouped = originalList.stream()
.collect(Collectors.groupingBy(r -> {
if ("0.5".equals(r.getSideType())) return "half";
else if ("1".equals(r.getSideType())) return "whole";
else return "unknown";
}));
List<SlaughterWeigh> halfList = grouped.getOrDefault("half", new ArrayList<>());
List<SlaughterWeigh> wholeList = grouped.getOrDefault("whole", new ArrayList<>());
List<SlaughterWeigh> unknownList = grouped.getOrDefault("unknown", new ArrayList<>());
特点:
- 可分多组(2 组、3 组、N 组)
- 键可以是任意类型(String、Enum 等)
- 可能返回 null(需用
getOrDefault) - 适合复杂分类场景
你的场景:只分两组(0.5 和非 0.5),用 groupingBy 有点大材小用
方案 3:两次 filter(效率较低,不推荐)
java
List<SlaughterWeigh> needMergeList = originalList.stream()
.filter(r -> "0.5".equals(r.getSideType()))
.collect(Collectors.toList());
List<SlaughterWeigh> normalList = originalList.stream()
.filter(r -> !"0.5".equals(r.getSideType()))
.collect(Collectors.toList());
特点:
- 代码看着简洁
- 性能最差:遍历两次列表
- 列表很大时(如 10 万条),耗时是其他方式的 2 倍
- 每增加一个分组就要多遍历一次
对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| 当前 for 循环 | 直观易懂,一次遍历 | 代码稍长 |
partitioningBy |
一次遍历,返回 Map | 需要理解 API |
groupingBy |
灵活,可多分组 | 稍复杂 |
两次 filter |
简洁 | 遍历两次,效率低 |
| 对比维度 | for 循环 | partitioningBy | groupingBy | 两次 filter |
|---|---|---|---|---|
| 代码行数 | 6 行 | 4 行 | 4 行 | 4 行 |
| 遍历次数 | 1 次 ✅ | 1 次 ✅ | 1 次 ✅ | 2 次 ❌ |
| 时间复杂度 | O(n) | O(n) | O(n) | O(2n) |
| 创建列表数 | 2 个 | 2 个(在 Map 中) | 2 个(在 Map 中) | 2 个 |
| 空值安全性 | 完全控制 | 不会返回 null,空列表自动处理 | 可能返回 null(需 getOrDefault) | 不会返回 null |
| 适用分组数 | 任意 | 只能 2 组(true/false) | 任意多组 | 每组需一次遍历 |
| 你的场景适配 | ⭐⭐⭐ 完美适配 | ⭐⭐⭐ 完美适配(二分类) | ⭐⭐☆ 杀鸡用牛刀 | ⭐☆☆ 性能差 |
| 可读性(新手) | ⭐⭐⭐ 最直观 | ⭐⭐☆ 需了解 API | ⭐⭐☆ 需了解 API | ⭐⭐⭐ 直观 |
| 可读性(熟练) | ⭐⭐☆ 略啰嗦 | ⭐⭐⭐ 函数式简洁 | ⭐⭐⭐ 函数式简洁 | ⭐☆☆ 重复遍历 |
| 调试难度 | ⭐⭐⭐ 易调试(可打断点) | ⭐⭐☆ 需熟悉 Stream | ⭐⭐☆ 需熟悉 Stream | ⭐⭐⭐ 易调试 |
| 空列表处理 | 已创建,可直接用 | 返回空列表(非 null) | 可能返回 null | 返回空列表(非 null) |
| 扩展性 | ⭐⭐⭐ 任意修改逻辑 | ⭐☆☆ 只能分两路 | ⭐⭐⭐ 可随时加分组 | ⭐☆☆ 加组需改遍历 |