我什么时候应该接受 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:23:05  来源:igfitidea点击:

When should I accept a parameter of Iterable<T> vs. Collection<T> in Java?

javacollections

提问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 Foos, 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>?

例如,考虑实现一个主要关注包含Foos集合和一些相关元数据的类型。这种类型的构造函数允许对象列表的一次性初始化。(元数据可以稍后设置。)这个构造函数应该接受什么类型?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 Iterableis 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 Iterableproduces Iteratorobjects. An Iteratorobject, by definition, iterates. Notice, that the Iteratorinterface makes no promise as to how many times next()can be called before hasNext()returns false. An Iteratorcould possibly iterate over Integer.MAX_VALUE + 1values before its hasNext()method returns false.

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

However, a Collectionis a special form of Iterable. Because a Collectioncannot have more than Integer.MAX_VALUEelements (by virtue of the size()method), it is naturally presumed that its Iteratorobjects will not iterate over this many elements.

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

Therefore, by accepting a Collectionrather 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 JPAwill find that the Repositoriesreturn 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 Tfrom the collection.

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

All Collections are Iterable(that is the interfaces which extend the Collectioninterface, so not Map!), so using Iterablein the business layer is merely a case of referring to a Collection by its super type and still allows the use of for-eachto 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)为此目的提供了便利方法。