我何时应该在Java中接受Iterable <T>与Collection <T>的参数?

Dan*_*nov 68 java collections

在Java 中使用Iterable<T>vs. 的注意事项是什么Collection<T>

例如,考虑实现一个主要涉及包含Foos 集合和某些关联元数据的类型.此类型的构造函数允许一次性初始化对象列表.(可以稍后设置元数据.)此构造函数应接受哪种类型?Iterable<Foo>,还是Collection<Foo>

这个决定有哪些考虑因素?

继通过模式库类型,如提出ArrayList(可从任何被初始化Collection,但不是一个Iterable),会导致我使用Collection<Foo>.

但是,为什么不接受Iterable<Foo>,因为这足以满足初始化需求?为什么要求Collection消费者提供更高级别的功能(),而不是严格必要的(Iterable)?

Jon*_*eet 63

之前存在许多集合类型Iterable<T>(仅在1.5中引入) - 没有理由添加构造函数以接受Iterable<T> , Collection<T>但是更改现有构造函数将是一个重大变化.

我会个人使用,Iterable<T>如果它允许你做你想要的一切.它对于呼叫者来说更灵活,特别是它允许您使用Google Java Collections(毫无疑问是类似的库)进行相对简单的过滤/投影等.

  • @finnw:它将与源代码兼容,但不兼容二进制:使用当前构造函数的现有(已编译)类将中断(因为它们明确地调用Collection-param构造函数)并需要重新编译. (18认同)

Ada*_*ter 22

Iterable生产Iterator对象.根据Iterator定义,对象是迭代的.请注意,Iterator接口不会保证next()hasNext()返回之前可以调用多少次false.一种Iterator可能可能遍历Integer.MAX_VALUE + 1其前值hasNext()方法返回false.

但是,a Collection是一种特殊的形式Iterable.因为a Collection不能有多个Integer.MAX_VALUE元素(凭借该size()方法),所以自然会假设它的Iterator对象不会迭代这么多元素.

因此,通过接受a Collection而不是a Iterable,你的类可以保证传递了多少元素.如果你的类本身就是一个,这是特别理想的Collection.

只是我的两分钱......

  • 而且,实际上,`Collection`也可以大于Interger.MAX_VALUE,然后size方法只返回Integer.MAX_VALUE.`Collection`的优点主要是`size()`方法(其他一切都可以在Iterator和size之上实现,如AbstractCollection所示),所以在迭代**之前需要大小时使用Collection**,不是你只想迭代的时候. (11认同)
  • 这不允许相当​​不合理的*迭代,代价是也不允许非收集,完全合理的迭代. (4认同)
  • 对![Javadoc proof!](http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html#size()) (4认同)
  • @Paŭlo:哇,我不知道`Collection.size()`返回`Integer.MAX_VALUE`,如果它包含的元素多于那么多! (2认同)

8bi*_*kie 9

用户Spring Data JPA会发现Repositories返回类型的集合Iterable<T>.

在我过去使用过的项目中Spring,我发现在检索后对Collection进行操作的需要经常要求Iterable<T>在业务层中使用,而不是Collection<T>为了T从集合中选择一个Object .

所有集合都是Iterable(这是扩展Collection接口的接口,所以不是Map!),因此Iterable在业务层中使用仅仅是通过其超类型引用Collection并仍然允许使用for-each迭代的情况.

如果你需要操纵集合的内容,一个方便的方法可以让你来填充新的Collection,所以你可以利用的contains(),remove()等与原来收集的数据.

或者,流行的第三方API(例如Google Guava和Apache Commons)为此提供了便利方法.


Mic*_*ers 8

使用最常用的界面.因为你要做的就是迭代,然后我会说Iterable是要走的路(因为它允许懒惰的迭代器等).你不关心迭代器的来源,所以不要超过你的限制.