8

我经常在很多地方读到应该避免返回 aiterable并改为返回 a collection。例如 -

public Iterable<Maze> Portals() {     
    // a list of some maze configurations
    List<Maze> mazes = createMazes();
    ...
    return Collections.unmodifiableList(mazes);
}

由于返回 aniterable仅对在foreach循环中使用它有用,因此 whilecollection已经提供了 aniterator并提供了更多控制。你能告诉我什么时候专门返回iterable一个方法是有益的吗?或者我们应该总是返回 a collection

注意:这个问题与 Guava 库无关

4

4 回答 4

13

Iterable当我们需要延迟加载包含大量元素的集合时,返回 an会很有用。

Google Collections FAQ中的以下引用似乎支持延迟加载的想法:

为什么如此强调迭代器和迭代器?

通常,当 Iterable 或 Iterator 就足够时,我们的方法不需要传入 Collection。这种区别对我们很重要,因为有时在谷歌我们处理大量数据,这些数据可能太大而无法放入内存,但可以在某些计算过程中从头到尾遍历。这样的数据结构可以实现为集合,但它们的大多数方法要么抛出异常,要么返回错误的答案,要么执行得很糟糕。对于这些情况,Collection 非常不合适;圆孔中的方形钉。

Iterator 代表一种单向可滚动的元素“流”,而 Iterable 是任何可以产生独立迭代器的东西。Collection 远不止于此,因此我们仅在需要时才需要它。

于 2013-10-20T07:43:12.110 回答
2

我可以看到优点和缺点:

  • 一个优点是它Iterable的界面比Collection. 如果你有一个非标准的集合类型,它可能IterableCollection. 确实,有一些集合的某些Collection方法难以实现。例如,惰性集合类型和您不想依赖标准equals(Object)方法来确定成员资格的集合。

  • 一个缺点是Iterable功能很差。如果您有一个实现 的具体类型Collection,并且您将其返回为Iterable,那么您将消除代码可以(直接)调用各种有用的集合方法的可能性。

  • 在某些情况下,Iterable 或 Collection 都不合适;例如原始类型的专业集合......您需要避免使用原始包装类型的开销。

你不能说返回一个Iterable. 视情况而定;例如,您正在设计的 API 的目的,以及您想要/需要对其施加的要求或约束。

于 2013-10-20T08:34:27.287 回答
1

问题是,如果底层集合发生变化,你就会遇到麻烦。如果您使用的是引发concurrentmodification异常的集合,那么您也必须处理它,但是使用集合就不会有这样的问题。

于 2013-10-20T07:18:30.317 回答
1

返回对所讨论的用途有意义的最具体的类型。例如,如果您有一个创建新集合的方法,或者您可以轻松地将集合包装在不可修改的包装器中,将集合返回为 a Collection,甚至是Listor Set,会使客户端开发人员的生活更轻松一些。

Iterable对于可以即时生成值的代码,返回是有意义的;例如,您可以想象一个斐波那契生成器,它创建了一个Iterator计算下一个数字而不是尝试存储一些查找表的数字。如果您正在编写这样一种“流式”API 可能有用的框架或接口代码(Guava 及其函数类在这方面做得很好),那么指定Iterable而不是集合类型可能值得失去灵活性消费者方面。

于 2013-10-20T07:48:45.150 回答