当前位置: 首页 > 面试题库 >

Java 我应该返回集合还是流?

章增
2023-03-14
问题内容

假设我有一个将只读视图返回到成员列表的方法:

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,因为一次实现所有可能没有任何价值,这样做可能会产生巨大的堆压力。

如果调用者要做的只是遍历它(搜索,html" target="_blank">过滤器,聚合),则你应该更喜欢Stream,因为Stream已经内置了这些内容,因此不需要实现集合(特别是如果用户可能不处理集合的话)。整个结果。)这是一个非常普遍的情况。

即使你知道用户将对其进行多次迭代或以其他方式保留它,你仍然可能想返回一个Stream,原因很简单,无论你选择放入哪个Collection(例如ArrayList)都可能不是他们想要的形式,然后调用者无论如何都要复制它。如果你返回流,则他们可以collect(toCollection(factory))按照所需的形式进行获取。

上面的“首选Stream”案例主要是因为Stream更加灵活。你可以后期绑定到你的使用方式,而不会产生将其具体化为Collection的成本和约束。

当有很强的一致性要求时,必须返回集合的一种情况是,必须为移动目标生成一致的快照。然后,你需要将元素放入不会更改的集合中。

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



 类似资料:
  • 假设我有一个方法将只读视图返回到成员列表中: 进一步假设客户机所做的只是立即对列表进行一次迭代。也许是为了把玩家放进一个JList或者别的什么。客户端没有存储对列表的引用以供以后检查! 对于这种常见的场景,我是否应该返回一个流呢? 还是返回流在Java中不是惯用的?流被设计成总是在创建它们的同一个表达式中“终止”吗?

  • 问题内容: 我发现自己同意返回接口而不是具体的类。 原因很简单,我要松散耦合。 但是还会有其他影响或权衡吗? 问题答案: 对于List或ArrayList之类的类型,不应进行任何编译,并且应将List提升Code返回到接口。 如果这是通过诸如CopyOnWriteArrayList之类的并发包进行的,并且您使用的是addIfAbsent之类的方法(未在List接口中定义),您将发现自己受到限制。

  • 我发现自己同意返回一个接口,而不是一个具体的类。

  • 在构建API时,编写接口代码是一个很好的实践,因此返回CompletionStage似乎是一个最好的方法。然而,我意识到我碰巧总是在获得CompletionStage之后调用.ToCompletableFuture。在这种情况下,推荐的方法是什么?

  • 问题内容: 在这个问题中,如何在C 11中有效地选择标准库容器?是选择C 集合时要使用的便捷流程图。 我认为对于那些不确定应该使用哪个集合的人来说,这是一个有用的资源,因此我试图找到类似的Java流程图,但未能做到。 哪些资源和“备忘单”可用来帮助人们选择使用Java进行编程时使用的正确Collection?人们如何知道应该使用哪些List,Set和Map实现? 问题答案: 由于找不到相似的流程图

  • 在这个问题中,如何在C 11中有效地选择标准库容器?是选择C集合时使用的方便流程图。 我认为对于那些不确定应该使用哪个集合的人来说,这是一个有用的资源,所以我试图找到一个类似的Java流程图,但没能做到。 有哪些资源和“备忘单”可以帮助人们在用Java编程时选择正确的集合?人们如何知道他们应该使用什么列表、集合和映射实现?