我在使用Java时看到的缺点之一是,与其迭代版本相比,代码的可读性更低。
顺便说一句,这就是我所想的,但我只是给出一些上下文(为了避免the XY problem),我要问的是独立于此的问题,所以希望而不是能够被视为一个基于观点的问题。
封装通常会增加代码的可读性(同样,只是给定的上下文),所以我正在寻找最好的方法来封装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接口.
还有别的办法吗?
也许存在一个我可以用的图书馆?
也许我的OO意识是试图将封装强加于不想要的事情上,但我仍然不知道这是否可能。
发布于 2020-06-07 15:53:32
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());https://stackoverflow.com/questions/62247764
复制相似问题