什么时候应该在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
值。
但是, Collection
是Iterable
一种特殊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 ,则不确定线程是否拥有该对象。