Java 何时应接受Iterable<;的参数;T>;vs.收集<;T>;在爪哇?

Java 何时应接受Iterable<;的参数;T>;vs.收集<;T>;在爪哇?,java,collections,Java,Collections,在Java中使用vs的注意事项是什么 例如,考虑实现一个类型,该类型主要涉及包含 FoO 的集合,以及一些相关的元数据。此类型的构造函数允许一次性初始化对象列表。(元数据可以稍后设置。)此构造函数应接受什么类型可编辑的,或收藏 这一决定的考虑因素是什么 遵循库类型设置的模式,例如ArrayList(可以从任何Collection初始化,但不能从Iterable)将导致我使用Collection 但既然这足以满足初始化需要,为什么不接受Iterable?为什么消费者要求更高级别的功能(Collec

在Java中使用vs的注意事项是什么

例如,考虑实现一个类型,该类型主要涉及包含<代码> FoO 的集合,以及一些相关的元数据。此类型的构造函数允许一次性初始化对象列表。(元数据可以稍后设置。)此构造函数应接受什么类型<代码>可编辑的,或

收藏

这一决定的考虑因素是什么

遵循库类型设置的模式,例如
ArrayList
(可以从任何
Collection
初始化,但不能从
Iterable
)将导致我使用
Collection


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

根据最小意外原则,您应该模拟Java收集模式并采用收集构造函数参数。这将使您后面的人稍微不那么困惑。

以前存在的许多集合类型(仅在1.5中引入)-几乎没有理由添加一个构造函数来接受
Iterable
,但是更改现有的构造函数将是一个突破性的更改


就我个人而言,我会使用
Iterable
,如果它允许你做任何你想做的事情。对于呼叫者来说,它更灵活,特别是它允许您使用Google Java集合(毫无疑问还有类似的库)进行相对简单的过滤/投影等操作。

您是正确的,因为它被认为是一种很好的实践,要求您所需的最通用的形式

尽可能使用最通用的界面。既然您要做的就是迭代,那么我想说,
Iterable
就是一种方法(因为它允许惰性迭代器,等等)。您不关心迭代器来自何处,因此不要过度限制它。

如果您选择Collection,那么您的类只能从集合初始化,如果您选择Iterable,那么您可以从Collection或Iterable进行初始化


由于两者的努力和性能将是相同的,因此在构造函数中接受Iterable是完全有意义的。

一个
Iterable
生成
迭代器
对象。根据定义,
迭代器
对象进行迭代。请注意,
迭代器
接口不保证在
hasNext()
返回
false
之前可以调用多少次
next()
迭代器
可能在其
hasNext()
方法返回
false
之前迭代
Integer.MAX_VALUE+1

但是,
集合
Iterable
的一种特殊形式。由于
集合
的元素不能超过
Integer.MAX_VALUE
(借助
size()
方法),因此自然假定其
迭代器
对象不会在这么多的元素上迭代

因此,通过接受
集合
而不是
Iterable
,您的类可以在一定程度上保证传入多少元素。如果类本身是一个
集合
,则这一点尤其可取


只有我的两分钱…

一些构造函数,例如ArrayList(集合c),使用toArray()方法来提高效率。

请参阅
对于首选迭代器,尤其是在处理大量数据时,这是一个不错的论据。一个可能有帮助的类比是思考向前只读游标和可滚动游标之间的区别。

Spring Data JPA的用户将发现
存储库
返回类型为
Iterable的集合。

在我过去从事的使用
Spring
的项目中,我发现在检索后需要对集合进行操作,这通常要求在业务层中使用
Iterable
,而不是
Collection
,以便从集合中选择对象
T

所有集合都是
Iterable
(即扩展
Collection
接口的接口,因此不是
Map
!),因此在业务层中使用
Iterable
,只是按集合的超类型引用集合的一种情况,仍然允许对每个
使用

如果您需要操作集合的内容,一种方便的方法将允许您填充新的
集合
,因此您可以使用原始集合数据使用
包含()
删除()
,等等


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

关于这一点,有一篇很棒的文章[here][1]。[1] :这不允许相当不合理的iterables,同时也不允许非集合、完全合理的iterables。事实上,
集合
也可以大于Integer.MAX\u值,那么size方法只返回Integer.MAX\u值。
Collection
的优点主要是
size()
方法(其他一切都可以在迭代器和size之上实现,如AbstractCollection所示),所以在迭代之前需要大小时使用集合,而不是只想迭代。@Paŭlo:哇,我不知道
Collection.size()
返回
整数。最大值
如果它包含的元素超过了那么多!是的!我不同意-Iterable仍然允许您将集合作为参数,但正如John所说,它允许您传递其他参数