java.util.Collection 为什么不实现新的 Stream 接口? [英] Why doesn't java.util.Collection implement the new Stream interface?

查看:23
本文介绍了java.util.Collection 为什么不实现新的 Stream 接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是花了一些时间开始研究关于流和 lambda 的 java-8 嗡嗡声.令我惊讶的是,您不能直接在 java.util.Collection 上应用流操作,例如 .map().filter()>.java.util.Collection 接口没有扩展的技术原因是否存在这些 Stream 操作的默认实现?

I just took some time to start looking into the java-8 buzz about streams and lambdas. What surprised me is that you cannot apply the Stream operations, like .map(), .filter() directly on a java.util.Collection. Is there a technical reason why the java.util.Collection interface was not extended with default implementations of these Stream operations?

谷歌一下,我看到很多人按照以下模式编码的例子:

Googling a bit, I see lots of examples of people coding along the pattern of:

List<String> list = someListExpression;
List<String> anotherList = list.stream().map(x -> f(x)).collect(Collectors.toList());

如果你的代码中有很多这样的流操作,这会变得非常笨拙.由于 .stream().collect() 和你想表达的东西完全无关,你宁愿说:

which becomes very clumsy, if you have a lot of these stream-operations in your code. Since .stream() and .collect() are completely irrelevant to what you want to express, you would rather like to say:

List<String> list = someListExpression;
List<String> anotherList = list.map(x -> f(x));

推荐答案

是的,做出这些决定是有充分理由的 :)

Yes, there are excellent reasons for these decisions :)

关键是eagerlazy操作的区别.您在第一个问题下给出的示例显示了急切操作,其中映射或过滤列表会生成一个新列表.这没有什么错,但它通常不是你想要的,因为你经常做的工作比你需要的多;急切操作必须对每个元素进行操作,并产生一个新的集合.如果您要组合多个操作(filter-map-reduce),您需要做很多额外的工作.另一方面,懒惰的操作组合得很漂亮;如果你这样做:

The key is the difference between eager and lazy operations. The examples you give under the first question show eager operations where mapping or filtering a list produces a new list. There's nothing wrong with this, but it is often not what you want, because you're often doing way more work than you need; an eager operation must operate on every element, and produce a new collection. If you're composing multiple operations (filter-map-reduce), you're doing a lot of extra work. On the other hand, lazy operations compose beautifully; if you do:

Optional<Person> tallestGuy = people.stream()
                                    .filter(p -> p.getGender() == MALE)
                                    .max(comparing(Person::getHeight));

过滤器和减少(最大)操作被融合到一起.这是非常有效的.

the filter and reduce (max) operations are fused together into a single pass. This is very efficient.

那么,为什么不直接在 List 上公开 Stream 方法呢?嗯,我们就这样试过了.在众多其他原因中,我们发现混合像 filter() 这样的惰性方法和像 removeAll() 这样的急切方法会让用户感到困惑.通过将惰性方法分组到一个单独的抽象中,它变得更加清晰;List 上的方法是那些改变列表的方法;Stream 上的方法是对数据序列进行可组合的惰性操作的方法,而不管数据位于何处.

So, why not expose the Stream methods right on List? Well, we tried it like that. Among numerous other reasons, we found that mixing lazy methods like filter() and eager methods like removeAll() was confusing to users. By grouping the lazy methods into a separate abstraction, it becomes much clearer; the methods on List are those that mutate the list; the methods on Stream are those that deal in composible, lazy operations on data sequences regardless of where that data lives.

所以,如果您想做非常简单的事情,您建议的方式很棒,但是当您尝试在此基础上进行构建时,它就会开始分崩离析.额外的 stream() 方法烦人吗?当然.但是保持数据结构(主要是关于在内存中组织数据)和流(主要是关于组合聚合行为)的抽象可以更好地分离更复杂的操作.

So, the way you suggest it is great if you want to do really simple things, but starts to fall apart when you try to build on it. Is the extra stream() method annoying? Sure. But keeping the abstractions for data structures (which are largely about organizing data in memory) and streams (which are largely about composing aggregate behavior) separate scales better to more sophisticated operations.

对于你的第二个问题,你可以相对容易地做到这一点:实现这样的流方法:

To your second question, you can do this relatively easily: implement the stream methods like this:

public<U> Stream<U> map(Function<T,U> mapper) { return convertToStream().map(mapper); }

但这只是逆流而上;最好只实现一个高效的 stream() 方法.

But that's just swimming against the tide; better to just implement an efficient stream() method.

这篇关于java.util.Collection 为什么不实现新的 Stream 接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆