如何封装Java Streams操作 - java

Improve this question

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

顺便说一句,这就是我的想法,但是我只是给出一些上下文(以避免the XY problem),我要问的是与此无关的,因此希望这将而不是视为基于意见的问题。

封装通常可以提高代码的可读性(再次提供给定的上下文),因此我正在寻找封装Java Stream操作的最佳方法。

例如,这是一系列以典型方式(无封装)实现的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]
    }

这是我通过添加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]
    } 

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

新方法提高了可读性(IMHO),并且可以进行单元测试(这是事实)。
上面的代码可以工作,但是看起来不是很漂亮或干净,理想情况下,我希望能够编写如下代码:

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

                // This obviously does not compile
                .filterOutEvenNumbersAndMultiplyByTwo()

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

我想可以做到,但是需要大量的精力,因为我必须实现Stream接口。

还有另一种方法吗?
也许我可以使用一个图书馆?
也许我的面向对象的想法正在试图对并非本来打算的东西进行封装,但是我仍然想知道是否有可能。

参考方案

filterOutEvenNumbers只是一个谓词。multiplyByTwo是一个地图操作。

// we can unit test these
IntPredicate filterOutEvenNumbers = i -> i % 2 != 0
IntUnaryOperator multiplyByTwo = i -> i * 2;

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

IntStream.range(1, 10)
    .filter(filterOutEvenNumbers)
    .map(multiplyByTwo)
    .boxed()
    .collect(Collectors.toList());

Java 8`Stream`可以并行运行,甚至不需要您吗? - java

如我所见,在使用Java 8 Stream时,显而易见的代码无论是“对象”流还是原始流(即IntStream和朋友)都将仅使用:someStreamableResource.stream().whatever() 但是,然后,相当多的“流媒体资源”也有了.parallelStream()。读取javadoc时不清楚的是.stream()流是否始终是顺序的,以…

JAVA 8具有任何匹配属性的对象的过滤器列表 - java

我的要求是通过匹配任何属性的字符串来过滤对象列表。例如,假设Contact类具有三个属性:街道,城市,电话。我知道java流过滤器是如何工作的,在这里我必须将输入字符串与每个属性进行比较,如下所示:contactList.stream().filter(contact -> contact.getStreet().equals("dubai&…

检查Optional中是否存在null属性,并返回String Java Stream API - java

我有以下class Person private String firstName; private String familyName; // Setters and Getters 我有以下方法public String getFullName(Optional<Person> persons) { return persons .map(p…

Java:正则表达式模式匹配器是否有大小限制? - java

我的模式类似于OR:“word1 | word2 | word3”我大约有800个字。可能有问题吗? 参考方案 您仅受记忆和理智的限制。 :)

Java:线程池如何将线程映射到可运行对象 - java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …