在方法中返回iterable是不好的做法吗?

时间:2013-10-20 07:13:11

标签: java collections iterator

我经常在许多地方读过,应该避免返回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库无关

4 个答案:

答案 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而不是集合类型可能是值得的消费者方面失去灵活性。