可迭代与迭代器作为返回行为(最佳实践?)

Posted

技术标签:

【中文标题】可迭代与迭代器作为返回行为(最佳实践?)【英文标题】:Iterable vs Iterator as a return behavior (Best Practice?) 【发布时间】:2012-05-21 19:19:37 【问题描述】:

我只是想知道您对将所有 Collections 函数输出更改为 Iterable 类型的意见。

在我看来,这可能是当今 Java 中最常见的代码,每个人在 99% 的时间里总是返回一个 List/Set/Map,但不应该是返回类似

的标准
    public final Iterable<String> myMethod() 
            return new Iterable<String>() 
                  @Override
                  public Iterator<String> iterator() return myVar.getColl();
            ;
    

这很糟糕吗?你知道所有的 DAO 类,这些东西就像

    Iterable<String> getName()
    Iterable<Integer> getNums()
    Iterable<String> getStuff()

而不是

    List<String> getName()
    List<Integer> getNums()
    Set<String> getStuff()

毕竟,99% 的时间你都会在 for 循环中使用它...

你觉得怎么样?

【问题讨论】:

使用集合,您通常还需要测试项目是否存在 - 这需要实际集合。 你说得对,把Set放在那里很愚蠢,特别是没有顺序的HashSet。 【参考方案1】:

这将是一个非常糟糕的计划。

我不会说 90% 的时间您只是在 for 循环中使用它。也许是 40-50%。其余时间,您需要更多信息:sizecontainsget(int)

此外,返回类型本身就是一种文档。返回 Set 保证元素是唯一的。返回一个 List 文档,表明元素将处于一致的顺序。

我不建议返回特定的集合实现,如 HashSetArrayList,但我通常更愿意返回 SetList 而不是 CollectionIterable,如果该选项可用。

【讨论】:

你是对的。但我的意思是对于那些你知道你只想要一个列表/一组东西来迭代的情况,这对我来说大多数情况下,你认为这样做好吗? 当然不会将ListSet 包装在可迭代对象中。如果您希望返回类型为Iterable,只需返回List,即Iterable 实例。但老实说,我仍然更愿意返回ListSet【参考方案2】:

List、Set 和 Map 是接口,因此它们不依赖于特定的实现。所以它们是返回类型的好候选。

List/etc 和 Iterable/Iterator 的区别在于访问的种类。一种是随机访问,您可以直接访问所有数据,而 Iterable 避免了所有可用数据的需要。在您拥有大量数据并且将其全部到位的情况下是理想的选择。示例:迭代大型数据库结果集。

所以这取决于您访问的内容。如果您的数据可能很大并且必须需要迭代以避免性能下降,那么请使用迭代器强制它。在其他情况下,列表是可以的。

编辑:返回一个迭代器意味着你唯一能做的就是在没有其他可能性的情况下循环遍历这些项目。如果您需要这种权衡来确保性能,可以,但如上所述,仅在需要时使用。

【讨论】:

【参考方案3】:

嗯,你编码的部分是正确的:

您需要测试项目的某些方法,例如:

    size contains() get(index) exists()

因此,您应该重新考虑您的新架构或使用此方法覆盖它,以便每次都能满足您的需要。

【讨论】:

以上是关于可迭代与迭代器作为返回行为(最佳实践?)的主要内容,如果未能解决你的问题,请参考以下文章

逐行迭代文本文件的内容 - 是不是有最佳实践? (与 PMD 的 AssignmentInOperand 相比)

TFS 和 Scrum - 区域、迭代、积压迭代、冲刺迭代的最佳实践配置

auto和decltype的最佳实践

《virtual san 最佳实践》节选 Virtual SAN的发展与现状

Object/Map 何为最佳实践

auto和decltype的最佳实践