我什么时候应该接受 Java 中 Iterable<T> 与 Collection<T> 的参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1159797/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When should I accept a parameter of Iterable<T> vs. Collection<T> in Java?
提问by Daniel Fortunov
What are the considerations of using Iterable<T>
vs. Collection<T>
in Java?
在 Java中使用Iterable<T>
vs.的注意事项是什么Collection<T>
?
For example, consider implementing a type that is primarily concerned with containing a collection of Foo
s, and some associated metadata. The constructor of this type allows one-time initialisation of the object list. (The metadata can be set later.) What type should this constructor accept? Iterable<Foo>
, or Collection<Foo>
?
例如,考虑实现一个主要关注包含Foo
s集合和一些相关元数据的类型。这种类型的构造函数允许对象列表的一次性初始化。(元数据可以稍后设置。)这个构造函数应该接受什么类型?Iterable<Foo>
,或Collection<Foo>
?
What are the considerations for this decision?
这个决定的考虑是什么?
Following the pattern set forth by library types such as ArrayList
(which can be initialised from any Collection
, but notan Iterable
) would lead me to use Collection<Foo>
.
通过库类型,如下面列出的模式集合ArrayList
(这可以从任何被初始化Collection
,但不是一个Iterable
),会导致我使用Collection<Foo>
。
But why not accept Iterable<Foo>
, given that this is is sufficient for the initialisation needs? Why demand a higher level of functionality (Collection
) from the consumer, than what is strictly necessary (Iterable
)?
但是为什么不接受Iterable<Foo>
,因为这足以满足初始化需要?为什么要求Collection
消费者提供更高级别的功能 ( ),而不是绝对必要的 ( Iterable
)?
采纳答案by Jon Skeet
Many of the collection types existed before Iterable<T>
(which was only introduced in 1.5) - there was little reason to add a constructor to accept Iterable<T>
as well asCollection<T>
but changing the existing constructor would have been a breaking change.
许多集合类型之前就存在Iterable<T>
(仅在 1.5 中引入)——几乎没有理由添加一个构造函数来接受Iterable<T>
以及Collection<T>
但更改现有构造函数将是一个重大变化。
Personally I would use Iterable<T>
if that allows you to do everything you want it to. It's more flexible for callers, and in particular it lets you do relativelyeasy filtering/projection/etc using the Google Java Collections (and no doubt similar libraries).
就我个人而言,Iterable<T>
如果这允许你做你想做的一切,我会使用。它对调用者来说更加灵活,特别是它可以让您使用 Google Java Collections(毫无疑问是类似的库)进行相对简单的过滤/投影/等操作。
回答by Paul McKenzie
According to the principle of least surprise, you should emulate the Java collection pattern and take a Collection constructor arg. It will make the people who come after you slightly less puzzled.
根据最小意外原则,您应该模拟 Java 集合模式并采用 Collection 构造函数 arg。它会让你后面的人稍微不那么困惑。
回答by Steve B.
You're correct, as it's considered good practice to ask for the most general form of what you need.
您是对的,因为要求您需要的最一般形式被认为是一种很好的做法。
回答by Michael Myers
Use the most general interface that you can. Since all you're going to do is iterate, then I would say Iterable
is the way to go (since it allows lazy iterators, etc.). You don't care where the iterator is coming from, so don't restrict it more than you have to.
尽可能使用最通用的界面。既然你要做的就是迭代,那么我想说的Iterable
是要走的路(因为它允许惰性迭代器等)。你不在乎迭代器来自哪里,所以不要过度限制它。
回答by Patrick McDonald
If you go for Collection, then your class can be initialised from a collection only, if you go for Iterable, then you can initialise from either collection or iterable.
如果你选择 Collection,那么你的类只能从一个集合初始化,如果你选择 Iterable,那么你可以从集合或 iterable 初始化。
As the effort and performance for both is going to be the same, it makes total sense to accept Iterable in the constructor.
由于两者的工作量和性能将相同,因此在构造函数中接受 Iterable 是完全有意义的。
回答by Adam Paynter
An Iterable
produces Iterator
objects. An Iterator
object, by definition, iterates. Notice, that the Iterator
interface makes no promise as to how many times next()
can be called before hasNext()
returns false
. An Iterator
could possibly iterate over Integer.MAX_VALUE + 1
values before its hasNext()
method returns false
.
一个Iterable
产生Iterator
对象。根据Iterator
定义,一个对象会迭代。请注意,该Iterator
接口没有承诺next()
在hasNext()
返回之前可以调用多少次false
。AnIterator
可能会Integer.MAX_VALUE + 1
在其hasNext()
方法返回之前迭代值false
。
However, a Collection
is a special form of Iterable
. Because a Collection
cannot have more than Integer.MAX_VALUE
elements (by virtue of the size()
method), it is naturally presumed that its Iterator
objects will not iterate over this many elements.
但是, aCollection
是 的特殊形式Iterable
。因为 aCollection
不能有多个Integer.MAX_VALUE
元素(凭借该size()
方法),自然假定它的Iterator
对象不会迭代这么多元素。
Therefore, by accepting a Collection
rather than an Iterable
, your class can have some guarantee over how many elements are being passed in. This is especially desirable if your class is itself a Collection
.
因此,通过接受 aCollection
而不是 an Iterable
,您的类可以对传入的元素数量有一定的保证。如果您的类本身是 a ,这尤其可取Collection
。
Just my two cents...
只是我的两分钱...
回答by starblue
Some constructors, e.g. ArrayList(Collection c), use the toArray() method of Collection for efficiency.
一些构造函数,例如 ArrayList(Collection c),为了效率而使用 Collection 的 toArray() 方法。
回答by Rick
See "Why so much emphasis on Iterators and Iterables?" on the Google Collection FAQfor a decent argument for preferring Iterators, especially when dealing with a lot of data. One analogy that might help is to think the difference between forward-only read-only cursors and scrollable cursors.
请参阅“为什么如此强调迭代器和可迭代对象?” 在Google Collection 常见问题解答中为偏爱迭代器提供了一个不错的论据,尤其是在处理大量数据时。一个可能有帮助的类比是思考只进只读游标和可滚动游标之间的区别。
回答by 8bitjunkie
Users of Spring Data JPA
will find that the Repositories
return collections of type Iterable<T>.
的用户Spring Data JPA
会发现Repositories
返回的集合类型Iterable<T>.
On projects I've worked on in the past that use Spring
, I've found that the need to operate on a Collection after retrieval has often dictated that Iterable<T>
is used in the business layer rather than Collection<T>
in order to select an Object T
from the collection.
在我过去使用的项目中Spring
,我发现在检索后对集合进行操作的需要通常决定Iterable<T>
在业务层中使用它,而不是Collection<T>
为了T
从集合中选择一个对象。
All Collections are Iterable
(that is the interfaces which extend the Collection
interface, so not Map
!), so using Iterable
in the business layer is merely a case of referring to a Collection by its super type and still allows the use of for-each
to iterate.
所有集合都是Iterable
(即扩展Collection
接口的接口,所以不是Map
!),因此Iterable
在业务层中使用只是通过其超类型引用集合的情况,并且仍然允许使用for-each
迭代。
If you need to manipulate the contents of a collection, a convenience method would allow you to populate a new Collection
, so you can make use of contains()
, remove()
, etc with the original collection data.
如果你需要操纵集合的内容,一个方便的方法可以让你来填充新的Collection
,所以你可以利用的contains()
,remove()
等与原来收集的数据。
Alternatively, convenience methods are provided for this purpose by popular third party APIs such as Google Guava and Apache Commons.
或者,流行的第三方 API(例如 Google Guava 和 Apache Commons)为此目的提供了便利方法。