Rop*_*Rop 47 java lambda functional-programming java-8 java-stream
我花了一些时间开始研究关于流和lambdas的java-8嗡嗡声.让我吃惊的是,你不能应用流操作,例如.map()
,.filter()
直接上java.util.Collection
.是否存在技术原因导致java.util.Collection
接口未通过这些Stream操作的默认实现进行扩展?
谷歌搜索了一下,我看到很多人按照以下模式编码的例子:
List<String> list = someListExpression;
List<String> anotherList = list.stream().map(x -> f(x)).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
如果你的代码中有很多这些流操作,那就变得非常笨拙了.由于.stream()
并且.collect()
与您想表达的内容完全无关,您宁愿说:
List<String> list = someListExpression;
List<String> anotherList = list.map(x -> f(x));
Run Code Online (Sandbox Code Playgroud)
Bri*_*etz 88
是的,这些决定有很好的理由:)
关键是渴望和懒惰操作之间的区别.您在第一个问题下给出的示例显示了急切的操作,其中映射或过滤列表会生成新列表.这没有什么不对,但它往往不是你想要的,因为你经常做的工作比你需要的多; 渴望的操作必须对每个元素进行操作,并产生新的集合.如果你正在编写多个操作(filter-map-reduce),那么你需要做很多额外的工作.另一方面,懒惰的操作组合得很漂亮; 如果你这样做:
Optional<Person> tallestGuy = people.stream()
.filter(p -> p.getGender() == MALE)
.max(comparing(Person::getHeight));
Run Code Online (Sandbox Code Playgroud)
过滤器和减少(最大)操作融合在一起成为一个通道.这非常有效.
那么,为什么不在List上公开Stream方法呢?好吧,我们就这样试过了.在众多其他原因中,我们发现混合惰性方法filter()
和急切方法removeAll()
会让用户感到困惑.通过将惰性方法分组为单独的抽象,它变得更加清晰; 方法List
是那些改变列表的方法; 这些方法Stream
是那些处理数据序列的可组合,懒惰操作的方法,无论数据存在于何处.
所以,如果你想做一些非常简单的事情,那么你建议它的方式很棒,但是当你尝试在它上面构建时,它会开始分崩离析.额外的stream()
方法烦人吗?当然.但是,保持数据结构的抽象(主要是关于在内存中组织数据)和流(主要是关于组合聚合行为)将更好地扩展到更复杂的操作.
对于第二个问题,您可以相对轻松地执行此操作:实现如下的流方法:
public<U> Stream<U> map(Function<T,U> mapper) { return convertToStream().map(mapper); }
Run Code Online (Sandbox Code Playgroud)
但那只是逆流而上; 更好地实现一个有效的stream()方法.
归档时间: |
|
查看次数: |
3445 次 |
最近记录: |