返回流而不是列表

Returning stream rather than list

在 Java 8 中,我越来越多地将 Collection return 值替换为 Stream

所以我曾经拥有的地方:

public List<Element> getElementList() {
    return elements;
}

我现在正在使用:

public Stream<Element> streamElements() {
    return elements.stream();
}

我对此的论点是:

  1. 它强制底层列表的不变性
  2. 它隐藏了 一个基础列表的事实。稍后可以在不更改方法签名的情况下将其更改为集合或其他一些结构。
  3. 它很好地封装了该方法的用户应该对项目而不是列表做某事。
  4. 如果需要,以后可以简单地并行化。

事实上,现在,在我的代码中,return使用 List 或其他一些集合明确地承认用户可能认为该集合是可变的,并且期望能够更改它.

显然,其中一些可以通过不可变集合来实现。

我的问题是:有人能看出这种设计有什么缺点吗?与 returning a Stream 相比,不可变集合有什么优势吗?

我能想到几种情况:

  1. 当调用者真的想要 "get and hold" 值而不是只处理一次时。
  2. 当每次返回一个新对象时,内存或性能问题是不可接受的,返回一个静态对象是更可取的(这对于高性能计算是可能的,或者你希望在方法中有确定性的处理时间,所以你想要最少的 GC)。

但是可以简化很多处理。

我不是说你不应该 return 流,更不是说你永远不应该 return 流,但这样做也有很多缺点:

  • 它不会告诉 API 集合的用户是有序的 (List) 还是无序的 (Set),或者排序的 (SortedSet)
  • 它不会告诉 API 的用户集合是否可以包含重复项 (List) 或不包含重复项 (Set)
  • 它不允许用户轻松快速地访问列表的第一个或最后一个元素,甚至不知道它的大小。
  • 如果 API 的用户需要多次遍历集合,他将被迫将每个元素复制到一个新集合中。

我会说选择 return 一个流而不是一个集合也取决于你已经拥有的东西。如果集合已经具体化(考虑一个 JPA 实体,其 OneToMany 已经具体化为一个集合),我可能 return 对集合进行不可变包装。另一方面,如果 return 的集合是另一个集合的计算或转换的结果,returning 流可能是更好的选择。