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 逻辑

更优雅的方式是使用 Streamfilter() 方法来分离奇偶数:

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 上找到。


原始标题:How to Use if/else Logic in Java Streams | Baeldung