我经常在许多地方读过,应该避免返回iterable
并返回collection
。例如 -
public Iterable<Maze> Portals() {
// a list of some maze configurations
List<Maze> mazes = createMazes();
...
return Collections.unmodifiableList(mazes);
}
由于返回iterable
只对在foreach
循环中使用它有用,而collection
已提供iterator
并提供更多控制权。你能告诉我什么时候在方法中专门返回iterable
是有益的吗?或者我们应该总是返回collection
?
注意:这个问题与Guava库无关
答案 0 :(得分:12)
当我们需要懒洋洋地加载包含大量元素的集合时,返回Iterable
会很有用。
Google Collections FAQ的以下引用似乎支持延迟加载的想法:
为什么如此强调Iterators和Iterables?
通常,我们的方法不需要传入Collection 当Iterable或Iterator足够时。这种区别是 对我们很重要,因为有时在谷歌我们的工作量非常大 数据量可能太大而无法容纳在内存中,但是哪些数据 可以在某些过程中从头到尾遍历 计算。这样的数据结构可以实现为集合, 但他们的大多数方法都要抛出异常, 回答错误的答案,或者表现糟糕。对于这些情况, 收藏很不合适;圆孔中的方形钉。
Iterator表示元素的单向可滚动“流”,和 Iterable是可以产生独立迭代器的任何东西。一个 收集远不止于此,因此我们只需要它 需要。
答案 1 :(得分:2)
我可以看到优点和缺点:
一个优点是Iterable
是一个比Collection
更简单的界面。如果您使用的是非标准收藏类型,则可能更容易将其设为Iterable
而不是Collection
。实际上,有一些类型的集合,其中一些Collection
方法的实现存在问题。例如,懒惰的集合类型和集合,您不希望依赖标准equals(Object)
方法来确定成员资格。
一个缺点是Iterable
功能较差。如果你有一个实现Collection
的具体类型,并将它作为Iterable
返回,那么你将删除代码可以(直接)调用各种有用的集合方法的可能性。
在某些情况下,Iterable或Collection都不合适;例如原始类型的专家集合......您需要避免使用原始包装类型的开销。
你无法真正说出返回Iterable
是好还是坏。这取决于具体情况;例如您正在设计的API的目的,以及您希望/需要对其进行的要求或约束。
答案 2 :(得分:1)
问题在于,如果基础集合发生变化,您将遇到麻烦。
如果你正在使用一个抛出concurrentmodification
异常的集合,那么你也必须处理它,但是收集时没有这样的问题。
答案 3 :(得分:1)
返回对相关用途有意义的最具体类型。例如,如果你有一个创建新集合的方法,或者你可以轻松地将集合包装在一个不可修改的包装器中,将集合作为Collection
,甚至List
或{{1}返回},让客户开发人员的生活更轻松。
返回Set
对于可以在运行中生成值的代码有意义;你可以设想一个Fibonacci生成器,例如,它创建了一个Iterable
来计算下一个数字,而不是试图存储一些查找表。如果您正在编写框架或接口代码,其中这种“流式”API可能有用(Guava及其功能类可以做很多事情),那么指定Iterator
而不是集合类型可能是值得的消费者方面失去灵活性。