什么时候应该在Java中接受Iterable <T>与Collection <T>的参数?

在Java中使用Iterable<T>Collection<T>什么Iterable<T>

例如,考虑实现一个主要涉及包含Foo集合的types,以及一些关联的元数据。 这种types的构造函数允许一次初始化对象列表。 (元数据可以稍后设置。)这个构造函数应该接受什么types? Iterable<Foo>Collection<Foo>

这个决定有什么考虑?

遵循由ArrayList (可以从任何Collection初始化,但不是 Iterable )等库types提出的模式将导致我使用Collection<Foo>

但是为什么不接受Iterable<Foo> ,因为这对初始化需求来说已经足够了。 为什么要求消费者提供更高级别的function( Collection ),而不是严格需要( Iterable )呢?

许多集合types在Iterable<T>之前就存在(仅在1.5版中引入),没有理由添加构造函数来接受Iterable<T> 以及 Collection<T>但是改变现有的构造函数本来就是突破变化。

就个人而言,我会使用Iterable<T>如果这允许你做你想要的一切。 这对于调用者来说更加灵活,尤其是它可以让你使用Google Java Collections(毫无疑问,类似的库)进行相对简单的过滤/投影等。

一个Iterable产生Iterator对象。 Iterator对象按定义迭代 。 请注意, Iterator接口没有承诺在hasNext()返回false之前可以调用hasNext() 。 在hasNext()方法返回false之前, Iterator可能会迭代Integer.MAX_VALUE + 1值。

但是, CollectionIterable一种特殊forms。 由于Collection大小不能超过Integer.MAX_VALUE (通过size()方法),所以很自然地推测它的Iterator对象不会迭代这些元素。

因此,通过接受一个Collection而不是Iterable ,你的类可以保证有多less元素被传入。如果你的类本身就是一个Collection那么这是特别需要的。

只是我的两分钱…

使用最通用的界面,你可以。 由于所有你要做的是迭代,那么我会说Iterable是要走的路(因为它允许惰性迭代器等)。 你不关心迭代器来自哪里,所以不要超过你的限制。

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

在过去使用过Spring ,我发现需要在检索后对Collection进行操作时,经常要求在业务层中使用Iterable<T> ,而不是Collection<T>从集合中select一个对象T

所有集合都是可Iterable (也就是扩展了Collection接口的接口,所以不是Map !),所以在业务层中使用Iterable仅仅是一个引用集合的超types的情况,仍然允许使用for-each迭代。

如果你需要操作集合的内容,一个方便的方法将允许你填充一个新的Collection ,所以你可以使用contains()remove()等原始的集合数据。

或者,通过stream行的第三方API(例如Google Guava和Apache Commons)为此提供便利方法。

一些构造函数(如ArrayList(Collection c))使用Collection的toArray()方法来提高效率。

请参阅“为什么如此重视迭代器和迭代器?” 在Google集合常见问题解答中 ,为了更喜欢迭代器,特别是在处理大量数据时提供了一个合适的参数。 有一个比较有用的方法,就是考虑只读只读游标和可滚动游标之间的区别。

如果你使用Collection,那么你的类只能从一个集合初始化,如果你使用了Iterable,那么你可以从集合或迭代初始化。

由于两者的努力和性能将是相同的,所以在构造函数中接受Iterable是完全合理的。

根据最小惊喜的原则,您应该模仿Java集合模式并采用Collection构造函数arg。 这会让你后面的人稍微困惑一点。

你是正确的,因为要求你所需要的最一般的forms被认为是好的做法。

同步呢? 如果你要迭代一个集合,你需要在获取迭代器之前获得一个锁。

  synchronized(myList) { Iterator iter = myList.iterator(); while (iter.hasNext()) { iter.next(); ... } } 

如果您收到Iterator而不是Collection ,则不确定线程​​是否拥有该对象。