Vit*_*liy 7 java lambda api-design java-8
这是关于API设计的问题.在C#中添加扩展方法时,获取IEnumerable所有在所有集合上直接使用lambda表达式的方法.
随着Java中lambdas和默认方法的出现,我希望Collection能够实现Stream并为其所有方法提供默认实现.这样,我们就不需要调用stream()它来利用它提供的功率.
图书馆建筑师选择不太方便的方法的原因是什么?
来自Maurice Naftalin的Lambda FAQ:
为什么Stream操作没有直接在Collection上定义?
的API暴露的方法,如早期的草稿
filter,map和reduce上Collection或Iterable.但是,用户使用此设计的体验导致将"流"方法更正式地分离为他们自己的抽象.原因包括:
在方法
Collection如removeAll让就地修改,而相比之下,新方法,这在本质上更多的功能.在同一抽象上混合两种不同的方法迫使用户跟踪哪些是哪种.例如,给出声明Run Code Online (Sandbox Code Playgroud)Collection strings;两个非常相似的方法调用
Run Code Online (Sandbox Code Playgroud)strings.removeAll(s -> s.length() == 0); strings.filter(s -> s.length() == 0); // not supported in the current API会有惊人的不同结果; 第一个将从
String集合中删除所有空对象,而第二个将返回包含所有非空Strings 的流,而对集合没有影响.相反,当前设计确保只能过滤明确获得的流:
Run Code Online (Sandbox Code Playgroud)strings.stream().filter(s.length() == 0)...;省略号表示进一步的流操作,以终止操作结束.这使读者对滤波器的作用有了更清晰的直觉;
随着懒惰方法的添加
Collection,用户感到困惑的是一种感知但错误的需要来推断该集合是处于"懒惰模式"还是"急切模式".与其Collection为新功能和不同功能增加负担,提供Stream具有新功能的视图更为清晰;添加的方法越多
Collection,与现有第三方实现名称冲突的可能性就越大.通过仅添加一些方法(stream,parallel),大大减少了冲突的机会;访问并行视图仍需要视图转换; 顺序流和并行流视图之间的不对称是不自然的.比较,例如
Run Code Online (Sandbox Code Playgroud)coll.filter(...).map(...).reduce(...);同
Run Code Online (Sandbox Code Playgroud)coll.parallel().filter(...).map(...).reduce(...);这种不对称性在API文档中尤为明显,其中
Collection有许多新方法可以生成顺序流,但只有一种方法可以生成并行流,这些流将具有与之相同的方法Collection.StreamOps例如,将这些因素分解为一个单独的界面无济于事; 这将是,直觉相反,需要由双方执行Stream和Collection;对观点的统一处理也为将来的其他观点留下了空间.
| 归档时间: |
|
| 查看次数: |
339 次 |
| 最近记录: |