我在使用 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 思想正试图强制封装一些不应该的东西,但我仍然想知道它是否可能。
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)
| 归档时间: |
|
| 查看次数: |
147 次 |
| 最近记录: |