gpt4 book ai didi

java - 为什么 java.util.Collection 不实现新的 Stream 接口(interface)?

转载 作者:行者123 更新时间:2023-12-02 02:35:06 25 4
gpt4 key购买 nike

我刚刚花了一些时间开始研究有关流和 lambda 的 java-8 热潮。令我惊讶的是,您无法直接在 java.util.Collection 上应用 Stream 操作,例如 .map().filter() >。是否存在技术原因导致 java.util.Collection 接口(interface)未使用这些 Stream 操作的默认实现?

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

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

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

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

最佳答案

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

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

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

过滤器和归约(最大)操作被融合到一个 channel 中。这是非常有效的。

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

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

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

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

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

关于java - 为什么 java.util.Collection 不实现新的 Stream 接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57207996/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com