1. 概述
在本教程中,我们将探讨如何在 Java 8 的 Stream 中实现 if/else 逻辑。我们会通过一个简单的算法来区分奇数和偶数,借此演示不同的实现方式。
如果你对 Java 8 Stream 还不熟悉,可以先看看这篇入门文章。
2. 在 forEach() 中使用传统的 if/else 逻辑
首先,我们创建一个 Integer
列表,并在 forEach()
方法中使用传统的 if/else 逻辑:
List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
ints.stream()
.forEach(i -> {
if (i.intValue() % 2 == 0) {
Assert.assertTrue(i.intValue() % 2 == 0);
} else {
Assert.assertTrue(i.intValue() % 2 != 0);
}
});
✅ 在 forEach
中我们通过取模运算判断数字是奇数还是偶数。
当然,这段逻辑也可以封装成一个自定义的 Consumer 来复用:
List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Consumer<Integer> integerParityAsserter = i -> {
if (i % 2 == 0) {
Assert.assertTrue(i + " is not even", i % 2 == 0);
} else {
Assert.assertTrue(i + " is not odd", i % 2 != 0);
}
};
ints.stream()
.forEach(integerParityAsserter);
⚠️ 这样写的好处是逻辑清晰、可复用,也方便单元测试。
3. 使用 filter() 实现 if/else 逻辑
更优雅的方式是使用 Stream
的 filter()
方法来分离奇偶数:
Stream<Integer> evenIntegers = ints.stream()
.filter(i -> i.intValue() % 2 == 0);
Stream<Integer> oddIntegers = ints.stream()
.filter(i -> i.intValue() % 2 != 0);
evenIntegers.forEach(i -> Assert.assertTrue(i.intValue() % 2 == 0));
oddIntegers.forEach(i -> Assert.assertTrue(i.intValue() % 2 != 0));
✅ filter()
方法能将数据流按条件拆分为两个子流,一个处理偶数,一个处理奇数。
4. 使用 Collectors#groupingBy
还可以使用 groupingBy()
方法对数据进行分组:
List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Map<String, List<Integer>> resultMap = ints.stream()
.collect(Collectors.groupingBy(i -> i % 2 == 0 ? "even" : "odd"));
Assert.assertEquals(Arrays.asList(2, 4, 6, 8, 10), resultMap.get("even"));
Assert.assertEquals(Arrays.asList(1, 3, 5, 7, 9), resultMap.get("odd"));
✅ 通过三元运算符将数字分为 “even” 和 “odd” 两组,groupingBy()
会自动完成分组。
5. 使用 Collectors#partitioningBy
还有一个更专门的方法是 partitioningBy()
,它接受一个 Predicate
并将数据划分为两部分:
List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Map<Boolean, List<Integer>> resultMap = ints.stream()
.collect(Collectors.partitioningBy(i -> i % 2 == 0));
Assert.assertEquals(Arrays.asList(2, 4, 6, 8, 10), resultMap.get(true));
Assert.assertEquals(Arrays.asList(1, 3, 5, 7, 9), resultMap.get(false));
✅ partitioningBy()
返回一个 Map<Boolean, List>
,其中 true
对应满足条件的元素,false
对应不满足的。
6. 总结
在这篇文章中,我们展示了多种在 Java Stream 中实现 if/else 逻辑的方式:
- 使用
forEach()
和传统条件判断 - 封装为
Consumer
提高复用性 - 使用
filter()
分离数据流 - 使用
groupingBy()
按条件分组 - 使用
partitioningBy()
进行布尔划分
这些方法各有适用场景,选择哪种取决于你的具体需求。完整代码可以在 GitHub 上找到。