如何封装 Java Streams 操作

Víc*_*Gil 6 java java-stream

我在使用 Java StreamAPI时看到的缺点之一是,与其迭代版本相比,代码的可读性似乎较低。

顺便说一下,这就是我的想法,但我只是提供了一些背景信息(以避免XY 问题),我要问的问题与此无关,因此希望这不会被视为基于意见的问题。

封装通常会增加代码的可读性(同样,只是给定上下文),因此我正在寻找封装 JavaStream操作的最佳方法。

例如,这是以Stream典型方式(无封装)实现的一系列简单操作:

    void method1() {
        List<Integer> result = IntStream.range(1, 10)

                // Two Stream "intermediate" operations:
                .filter(i -> i % 2 != 0).map(i -> i * 2)

                .boxed().collect(Collectors.toList());

        log.debug("Result: {}", result);
        // Result: [2, 6, 10, 14, 18]
    }
Run Code Online (Sandbox Code Playgroud)

这是我通过添加filterOutEvenNumbersAndMultiplyByTwo方法来实现封装的第一个也是简单的尝试:

    IntStream filterOutEvenNumbersAndMultiplyByTwo(IntStream stream) {
        return stream.filter(i -> i % 2 != 0).map(i -> i * 2);
    }

    void method2() {
        List<Integer> result = filterOutEvenNumbersAndMultiplyByTwo(IntStream.range(1, 10))
                .boxed().collect(Collectors.toList());

        log.debug("Result: {}", result);
        // Result: [2, 6, 10, 14, 18]
    } 
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我Stream在一个新方法中封装了两个中间操作,在这种情况下这似乎没有多大意义,但这只是一个例子,可能有两个以上的Stream操作,还有更复杂的操作。

新方法提高了可读性(恕我直言)并且可以进行单元测试(这是事实)。
上面的代码有效,但它看起来不太好或干净,理想情况下,我希望能够编写如下内容:

        List<Integer> result = IntStream.range(1, 10)

                // This obviously does not compile
                .filterOutEvenNumbersAndMultiplyByTwo()

                .boxed().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我想它可以完成,但需要付出很大的努力,因为我必须实现Stream接口......

还有其他方法吗?
也许存在我可以使用的图书馆?
也许我的 OO 思想正试图强制封装一些不应该的东西,但我仍然想知道它是否可能。

Ram*_*ash 2

filterOutEvenNumbers只是一个谓词。 multiplyByTwo是一个映射操作。

// we can unit test these
IntPredicate filterOutEvenNumbers = i -> i % 2 != 0
IntUnaryOperator multiplyByTwo = i -> i * 2;
Run Code Online (Sandbox Code Playgroud)

您可以有 N 个谓词/映射操作。我们还可以在这里切换各种谓词/映射操作。

IntStream.range(1, 10)
    .filter(filterOutEvenNumbers)
    .map(multiplyByTwo)
    .boxed()
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)