java:返回一个集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2178319/
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
java: returning a collection
提问by Jason S
What's the best way to return a collection in Java?
在 Java 中返回集合的最佳方法是什么?
Should I allow the caller to provide a collection to add to? Or just return a List<>or Set<>of items? Or both?
我应该允许调用者提供要添加的集合吗?或者只是返回一个List<>或Set<>多个项目?或两者?
public class Item { ... }
public class SomeOtherClass
{
private List<Item> myItems;
public List<Item> getItems()
{
return Collections.unmodifiableList(this.myItems);
}
public void collectItems(Collection<? super Item> target)
{
target.addAll(myItems);
}
}
note:the above example assumes the pre-existence of a list that can be instantly returned. I am also interested in the appropriate answer when such a list does not previously exist and must be generated when the caller calls getItems() or collectItems(). (I have renamed collectItems based on the point raised by Mykola.)
注意:上面的例子假设一个可以立即返回的列表预先存在。当这样的列表以前不存在并且必须在调用者调用 getItems() 或 collectItems() 时生成时,我也对适当的答案感兴趣。(我根据 Mykola 提出的观点重命名了 collectItems。)
采纳答案by Geoff Reedy
I'd just prefer the List<Item> getItems()method. There's no real advantage to void getItems(Collection<? super Item> target)over the caller just doing myCollection.addAll(foo.getItems())performance or otherwise. Collections.unmodifiableXYZonly creates a wrapper, not a complete copy of the collection so if the wrapper is used immediately and discarded it will never make it out of the first generation and will be collected quickly with little overhead.
我只是更喜欢这种List<Item> getItems()方法。void getItems(Collection<? super Item> target)仅仅执行myCollection.addAll(foo.getItems())性能或其他方面的调用者并没有真正的优势。Collections.unmodifiableXYZ只创建一个包装器,而不是集合的完整副本,因此如果包装器被立即使用并丢弃,它将永远不会从第一代中退出,并且会以很少的开销快速收集。
If the collection of items is not always realized you might consider having getItems return Iterable<Item>when you don't know how many items there are. If you know the number of items and can write an iterator for them, then it's easy to write a custom subclass of AbstractCollectionand return that.
如果项目的集合并不总是被意识到,Iterable<Item>当您不知道有多少项目时,您可能会考虑让 getItems 返回。如果您知道项目的数量并且可以为它们编写迭代器,那么编写一个自定义子类AbstractCollection并返回它就很容易了。
回答by Mykola Golubyev
It is better (unless some performance issues) to return result in a functions via return. In that way it is more clear what is going on.
最好(除非某些性能问题)通过return. 这样就更清楚发生了什么。
If you choose second option (fill client's collection) than it would be better to rename function from getItemsto something like fillWithItemsto avoid ambiguous code.
如果您选择第二个选项(填充客户的集合),那么最好将函数重命名getItems为类似的名称fillWithItems以避免歧义代码。
Also don't forget about JavaBeans and its convention.
也不要忘记 JavaBeans 及其约定。
回答by Devon_C_Miller
Note: Returning a Set and returning a List have different implications.
注意:返回 Set 和返回 List 有不同的含义。
A Set has no duplicates and no stated order. Adding an element to a set might result in a different order of the elements.
Set 没有重复项,也没有规定的顺序。向集合中添加元素可能会导致元素的顺序不同。
A List may contain duplicates and adding an element will not (generally) change the overall order of the list.
列表可能包含重复项,添加元素不会(通常)改变列表的整体顺序。
As for how you return the list, I would use the first form:
至于如何返回列表,我将使用第一种形式:
public List<Item> getItems()
{
return Collections.unmodifiableList(this.myItems);
}
I can't think of a situation where the latter form would be of any benefit. A List is not like an array where the space can be pre-allocated. So, there's no performance savings by passing in a List.
我想不出后一种形式会有任何好处的情况。List 不像一个可以预先分配空间的数组。因此,传入 List 不会节省性能。
回答by Jay
The only reason I can think of to fill an existing collection rather than making a new one is when you have issues with the type of object in the collection. Like the Java library toArray(Object[] a) function, where the program doesn't know at compile time what the appropriate type of the elements of the array will be, so it can't just return, e.g. a String[]. So instead they have the caller pass in an array with the appropriate type of elements, and they fill that.
我能想到的填充现有集合而不是创建新集合的唯一原因是当您对集合中的对象类型有问题时。就像 Java 库 toArray(Object[] a) 函数一样,程序在编译时不知道数组元素的适当类型是什么,因此它不能只返回,例如 String[]。因此,他们让调用者传入一个具有适当类型元素的数组,然后填充它。
90% of the time you know exactly what types of objects you want to return, so you can just do it.
90% 的情况下,您确切地知道要返回什么类型的对象,因此您可以这样做。
回答by GreenieMeanie
You could change your signature to return a Collection or Iterable. For returning Iterable, you could return a new something-Iterable(myItems.iterator()) instead of myItems directly to avoid the client possibly trying to cast to a List (and modify it). If you don't want them modifying the List, also consider returning a Iterator also, but note that Iterable is better since you can directly use those in for-each loops.
您可以更改签名以返回集合或可迭代对象。对于返回 Iterable,您可以直接返回一个新的 something-Iterable(myItems.iterator()) 而不是 myItems,以避免客户端可能尝试转换为 List(并修改它)。如果您不希望它们修改 List,也可以考虑返回一个 Iterator,但请注意 Iterable 更好,因为您可以直接在 for-each 循环中使用它们。
Returning an Iterable both makes your intention clear and in the example above, prevents modification. The only implication is that you have lost random access, which may or may not be a problem for your needs.
返回 Iterable 既可以使您的意图明确,并且在上面的示例中可以防止修改。唯一的含义是您丢失了随机访问权限,这可能会也可能不会满足您的需求。
回答by Casey
You should return a the collection. It is a more common approach in Java than to use in/out parameters. I don't see any reason there would be a performance penalty for returning a large collection and it will be much cleaner code.
你应该返回一个集合。这是 Java 中比使用输入/输出参数更常见的方法。我看不出有任何理由会因为返回大集合而导致性能下降,而且代码会更简洁。
回答by TofuBeer
Given the way Java works you would generally expect the return version.
鉴于 Java 的工作方式,您通常会期望返回版本。
However if you need control over what type of collection is created then you would do the version where you pass it in as an argument.
但是,如果您需要控制创建什么类型的集合,那么您将执行将其作为参数传递的版本。
Usually nothing should care what type of collection is created, so you should generally go with the return version. Good use of the unmodifiableList by the way.
通常没有什么应该关心创建什么类型的集合,所以你通常应该使用返回版本。顺便说一下,很好地使用了 unmodifiableList。

