java - 我应该返回集合还是流?

标签 java collections java-8 encapsulation java-stream

假设我有一个方法可以将只读 View 返回到成员列表中:

class Team {
    private List<Player> players = new ArrayList<>();

    // ...

    public List<Player> getPlayers() {
        return Collections.unmodifiableList(players);
    }
}

进一步假设客户端所做的所有事情都是立即对列表进行一次迭代。也许将玩家放入 JList 或其他东西中。客户端确实存储对列表的引用以供以后检查!

鉴于这种常见情况,我应该返回一个流吗?

public Stream<Player> getPlayers() {
    return players.stream();
}

或者在 Java 中返回一个非惯用的流?流是否设计为始终在创建它们的同一表达式中“终止”?

最佳答案

一如既往,答案是“视情况而定”。这取决于返回的集合有多大。这取决于结果是否随时间变化,以及返回结果的一致性有多重要。这在很大程度上取决于用户可能如何使用答案。

首先,请注意,您始终可以从 Stream 中获取 Collection,反之亦然:

// If API returns Collection, convert with stream()
getFoo().stream()...

// If API returns Stream, use collect()
Collection<T> c = getFooStream().collect(toList());

所以问题是,哪个对您的来电者更有用。

如果您的结果可能是无限的,那么只有一个选择:Stream

如果您的结果可能非常大,您可能更喜欢 Stream,因为一次将其全部实现可能没有任何值(value),而且这样做可能会产生巨大的堆压力。

如果调用者要做的只是遍历它(搜索、过滤、聚合),你应该更喜欢 Stream,因为 Stream 已经内置了这些并且不需要具体化集合(特别是如果用户可能不会处理整个结果。)这是一种非常常见的情况。

即使您知道用户会多次迭代它或以其他方式保留它,您仍然可能希望返回一个 Stream,因为无论 Collection(例如,ArrayList)可能不是他们想要的形式,然后调用者无论如何都必须复制它。如果您返回 Stream,他们可以执行 collect(toCollection(factory)) 并以他们想要的形式得到它。

上述“更喜欢Stream”的情况大多源于Stream更加灵活;您可以后期绑定(bind)到如何使用它,而不会产生将其具体化为 Collection 的成本和限制。

您必须返回 Collection 的一种情况是存在强一致性要求,并且您必须生成移动目标的一致快照。然后,您需要将元素放入一个不会更改的集合中。

所以我想说,在大多数情况下,Stream 是正确的答案——它更灵活,不会强加通常不必要的实现成本,并且可以轻松转换为 Collection如果需要,您可以选择。但有时,您可能必须返回 Collection(例如,由于强一致性要求),或者您可能希望返回 Collection,因为您知道用户将如何使用它并且知道这对他们来说是最方便的。

如果您已经有一个合适的 Collection “闲置”,并且您的用户似乎更愿意将其作为 Collection 与之交互,那么这是合理的选择(虽然不是唯一的,而且更脆弱)只返回你所拥有的。

关于java - 我应该返回集合还是流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24676877/

相关文章:

Java 泛型代码

java - 如何导出带有凭证详细信息的理货分类账期初和期末余额?

java - 尝试通过 python 脚本启动 Minecraft 服务器时出现内存问题

ruby-on-rails - 如何检索关系/集合的特定属性?

java - Java 8 LocalDateTime 的周末过滤器

java - 映射嵌套可选?

java - Spring security 无法将属性 'secRole' 的类型 [java.lang.String] 的值转换为所需类型 [SecRole]

java - 给定一个 javafx.scene.image.Image 对象旋转它并产生一个旋转的 javafx.scene.image.Image 对象

java - Java 中具有自动索引的集合

collections - Java8 : Use filters/predicates along with disjunction