Should I return a Collection or a Stream?(我应该返回集合还是流?)
问题描述
假设我有一个方法可以将只读视图返回到成员列表中:
Suppose I have a method that returns a read-only view into a member list:
class Team {
private List<Player> players = new ArrayList<>();
// ...
public List<Player> getPlayers() {
return Collections.unmodifiableList(players);
}
}
进一步假设客户端所做的所有事情都是立即对列表进行一次迭代.也许将玩家放入 JList 或其他东西中.客户端确实不存储对列表的引用以供以后检查!
Further suppose that all the client does is iterate over the list once, immediately. Maybe to put the players into a JList or something. The client does not store a reference to the list for later inspection!
鉴于这种常见情况,我应该返回一个流吗?
Given this common scenario, should I return a stream instead?
public Stream<Player> getPlayers() {
return players.stream();
}
或者在 Java 中返回一个非惯用的流?流是否设计为始终终止"?在创建它们的同一表达式中?
Or is returning a stream non-idiomatic in Java? Were streams designed to always be "terminated" inside the same expression they were created in?
推荐答案
答案一如既往,视情况而定".这取决于返回的集合有多大.这取决于结果是否随时间变化,以及返回结果的一致性有多重要.这在很大程度上取决于用户可能如何使用答案.
The answer is, as always, "it depends". It depends on how big the returned collection will be. It depends on whether the result changes over time, and how important consistency of the returned result is. And it depends very much on how the user is likely to use the answer.
首先,请注意,您始终可以从 Stream
中获取 Collection
,反之亦然:
First, note that you can always get a Collection
from a Stream
, and vice versa:
// If API returns Collection, convert with stream()
getFoo().stream()...
// If API returns Stream, use collect()
Collection<T> c = getFooStream().collect(toList());
所以问题是,哪个对您的来电者更有用.
So the question is, which is more useful to your callers.
如果您的结果可能是无限的,那么只有一个选择:Stream
.
If your result might be infinite, there's only one choice: Stream
.
如果您的结果可能非常大,您可能更喜欢 Stream
,因为一次将其全部实现可能没有任何价值,而且这样做可能会产生巨大的堆压力.
If your result might be very large, you probably prefer Stream
, since there may not be any value in materializing it all at once, and doing so could create significant heap pressure.
如果调用者要做的只是遍历它(搜索、过滤、聚合),你应该更喜欢 Stream
,因为 Stream
已经内置了这些并且不需要具体化集合(特别是如果用户可能不会处理整个结果.)这是一种非常常见的情况.
If all the caller is going to do is iterate through it (search, filter, aggregate), you should prefer Stream
, since Stream
has these built-in already and there's no need to materialize a collection (especially if the user might not process the whole result.) This is a very common case.
即使您知道用户会多次迭代它或以其他方式保留它,您仍然可能希望返回一个 Stream
,因为无论 Collection您选择放入的代码>(例如,
ArrayList
)可能不是他们想要的形式,然后调用者无论如何都必须复制它.如果您返回 Stream
,他们可以执行 collect(toCollection(factory))
并以他们想要的形式得到它.
Even if you know that the user will iterate it multiple times or otherwise keep it around, you still may want to return a Stream
instead, for the simple fact that whatever Collection
you choose to put it in (e.g., ArrayList
) may not be the form they want, and then the caller has to copy it anyway. If you return a Stream
, they can do collect(toCollection(factory))
and get it in exactly the form they want.
上面的首选Stream
"案例大多源于 Stream
更灵活的事实;您可以后期绑定到如何使用它,而不会产生将其具体化为 Collection
的成本和限制.
The above "prefer Stream
" cases mostly derive from the fact that Stream
is more flexible; you can late-bind to how you use it without incurring the costs and constraints of materializing it to a Collection
.
您必须返回 Collection
的一种情况是存在强一致性要求,并且您必须生成移动目标的一致快照.然后,您需要将元素放入一个不会更改的集合中.
The one case where you must return a Collection
is when there are strong consistency requirements, and you have to produce a consistent snapshot of a moving target. Then, you will want put the elements into a collection that will not change.
所以我想说,在大多数情况下,Stream
是正确的答案——它更灵活,不会强加通常不必要的实现成本,并且可以轻松转换为 Collection如果需要,您可以选择.但有时,您可能必须返回 Collection
(例如,由于强一致性要求),或者您可能希望返回 Collection
,因为您知道用户将如何使用它并且知道这对他们来说是最方便的.
So I would say that most of the time, Stream
is the right answer — it is more flexible, it doesn't impose usually-unnecessary materialization costs, and can be easily turned into the Collection of your choice if needed. But sometimes, you may have to return a Collection
(say, due to strong consistency requirements), or you may want to return Collection
because you know how the user will be using it and know this is the most convenient thing for them.
如果您已经有一个合适的 Collection
闲置",并且您的用户似乎更愿意将其作为 Collection
与之交互,那么它就是一个合理的选择(虽然不是唯一的,而且更脆弱)只返回你所拥有的.
If you already have a suitable Collection
"lying around", and it seems likely that your users would rather interact with it as a Collection
, then it is a reasonable choice (though not the only one, and more brittle) to just return what you have.
这篇关于我应该返回集合还是流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:我应该返回集合还是流?
基础教程推荐
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- 降序排序:Java Map 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01
- Java:带有char数组的println给出乱码 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01