java 使用 List 还是 Collection 更好?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2917627/
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-10-29 23:27:20  来源:igfitidea点击:

Is it better to use List or Collection?

javalistcollectionsabstraction

提问by Vivin Paliath

I have an object that stores some data in a list. The implementation could change later, and I don't want to expose the internal implementation to the end user. However, the user must have the ability to modify and access this collection of data. Currently I have something like this:

我有一个将一些数据存储在列表中的对象。实现可能会在以后更改,我不想将内部实现公开给最终用户。但是,用户必须能够修改和访问此数据集合。目前我有这样的事情:

public List<SomeDataType> getData() {
   return this.data;
}

public void setData(List<SomeDataType> data) {
   this.data = data;
}

Does this mean that I have allowed the internal implementation details to leak out? Should I be doing this instead?

这是否意味着我允许内部实现细节泄露?我应该这样做吗?

public Collection<SomeDataType> getData() {
   return this.data;
}

public void setData(Collection<SomeDataType> data) {
   this.data = new ArrayList<SomeDataType>(data);
}

采纳答案by Matt H

It just depends, do you want your users to be able to index into the data? If yes, use List. Both are interfaces, so you're not leaking implementation details, really, you just need to decide the minimum functionality needed.

这只是取决于,您是否希望您的用户能够对数据进行索引?如果是,请使用列表。两者都是接口,因此您不会泄露实现细节,实际上,您只需要确定所需的最低功能即可。

回答by Shikhar Mishra

Returning a List is in line with programming to the Highest Suitable Interface.

返回列表符合编程到最高合适的接口。

Returning a Collection would cause ambiguity to the user, as a returned collection could be either: Set, List or Queue.

返回集合会给用户造成歧义,因为返回的集合可能是:Set、List 或 Queue。

回答by Brian M. Carr

Independent of the ability to index into the list via List.get(int), do the users (or you) have an expectation that the elements of the collection are in a reliable and predictable order? Can the collection have multiples of the same item? Both of these are expectations of lists that are not common to more general collections. These are the tests I use when determining which abstraction to expose to the end user.

独立于通过 List.get(int) 索引到列表的能力,用户(或您)是否期望集合的元素处于可靠且可预测的顺序?集合可以有多个相同的项目吗?这两个都是对更一般集合不常见的列表的期望。这些是我在确定向最终用户公开哪个抽象时使用的测试。

回答by Jay

When returning an implementation of an interface or class that is in a tall hierarchy, the rule of thumb is that the declared return type should be the HIGHEST level that provides the minimum functionality that you are prepared to guarantee to the caller, and that the caller reasonably needs. For example, suppose what you really return is an ArrayList. ArrayList implements List and Collection (among other things). If you expect the caller to need to use the get(int x) function, then it won't work to return a Collection, you'll need to return a List or ArrayList. As long as you don't see any reason why you would ever change your implementation to use something other than a list -- say a Set -- then the right answer is to return a List. I'm not sure if there's any function in ArrayList that isn't in List, but if there is, the same reasoning would apply. On the other hand, once you do return a List instead of a Collection, you have now locked in your implementation to some extent. The less you put in your API, the less restriction you put on future improvements.

当返回高层次结构中的接口或类的实现时,经验法则是声明的返回类型应该是提供您准备向调用者保证的最少功能的最高级别,并且调用者合理需要。例如,假设您真正返回的是一个 ArrayList。ArrayList 实现了 List 和 Collection(除其他外)。如果您希望调用者需要使用 get(int x) 函数,那么返回 Collection 将不起作用,您需要返回一个 List 或 ArrayList。只要您看不到任何理由为什么要更改您的实现以使用列表以外的其他东西——比如 Set——那么正确的答案是返回一个列表。我不确定 ArrayList 中是否有任何不在 List 中的函数,但如果有,同样的推理也适用。另一方面,一旦你确实返回了一个列表而不是一个集合,你现在已经在某种程度上锁定了你的实现。您在 API 中投入的越少,您对未来改进的限制就越少。

(In practice, I almost always return a List in such situations, and it has never burned me. But I probably really should return a Collection.)

(在实践中,我几乎总是在这种情况下返回一个 List,它从来没有让我失望。但我可能真的应该返回一个 Collection。)

回答by Alb

Using the most general type, which is Collection, makes the most sense unless there is some explicit reason to use the more specific type - List. But whatever you do, if this is an API for public consumption be clear in the documentation what it does; if it returns a shallow copy of the collection say so.

使用最通用的类​​型,即 Collection,最有意义,除非有一些明确的理由使用更具体的类型 - List。但是无论你做什么,如果这是一个供公众使用的 API,请在文档中明确它的作用;如果它返回集合的浅表副本,请说出来。

回答by EMP

Yes, your first alternative does leak implementation details if it's not part of your interface contract that the method will always return a List. Also, allowing user code to replace your collection instance is somewhat dangerous, because the implementation they pass in may not behave as you expect.

是的,如果该方法将始终返回列表不是您的接口合同的一部分,那么您的第一个替代方案确实会泄漏实现细节。此外,允许用户代码替换您的集合实例有些危险,因为它们传入的实现可能不会像您期望的那样运行。

Of course, it's all a matter of how much you trust your users. If you take the Python philosophy that "we're all consenting adults here" then the first method is just fine. If you think that your library will be used by inexperienced developers and you need to do all you can to "babysit" them and make sure they don't do something wrong then it's preferable not to let them set the collection and not to even return the actual collection. Instead return a (shallow) copy of it.

当然,这完全取决于您对用户的信任程度。如果您采用“我们都同意这里的成年人”的 Python 哲学,那么第一种方法就好了。如果您认为您的库将被没有经验的开发人员使用,并且您需要尽一切可能“照看”他们并确保他们不会做错事,那么最好不要让他们设置集合,甚至不要返回实际收藏。而是返回它的(浅)副本。

回答by Michael Aaron Safyan

It depends on what guarantees you want to provide the user. If the data is sequential such that the order of the elements matter and you are allowing duplicates, then use a list. If order of elements does not matter and duplicates may or may not be allowed, then use a collection. Since you are actually returning the underlying collection you should not have both a get and set function, only a get function, since the returned collection may be mutated. Also, providing a set function allows the type of collection to be changed by the user, whereas you probably want for the particular type to be controlled by you.

这取决于您想为用户提供什么保证。如果数据是连续的,以至于元素的顺序很重要并且您允许重复,则使用列表。如果元素的顺序无关紧要并且可能允许也可能不允许重复,则使用集合。由于您实际上是在返回底层集合,因此不应同时具有 get 和 set 函数,而应只有 get 函数,因为返回的集合可能会发生变异。此外,提供 set 函数允许用户更改集合的类型,而您可能希望特定类型由您控制。

回答by Cyberherbalist

Were I concerned with obscuring internal representation of my data to an outside user, I would use either XML or JSON. Either way, they're fairly universal.

如果我担心向外部用户隐藏我的数据的内部表示,我会使用 XML 或 JSON。无论哪种方式,它们都是相当普遍的。