java 集合接口与数组

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

Collection Interface vs arrays

javacollections

提问by kreeSeeker

We are learning about the Collection Interface and I was wondering if you all have any good advice for it's general use? What can you do with an Collection that you cannot do with an array? What can you do with an array that you cannot do with a Collection(besides allowing duplicates)?

我们正在学习 Collection Interface,我想知道你们是否对它的一般用途有什么好的建议?你可以用 Collection 做什么而不能用数组做什么?你可以用数组做什么而不能用集合做什么(除了允许重复)?

回答by Kevin Bourrillion

It's easy if you think of it like this: Collections are better than object arrays in basically every way imaginable.

如果你这样想就很容易了:集合基本上在所有可以想象的方面都比对象数组好。

You should prefer List<Foo>over Foo[]whenever possible. Consider:

你应该更喜欢List<Foo>Foo[]只要有可能。考虑:

  • A collection can be mutable or immutable. A nonempty array must always be mutable.
  • A collection can be thread-safe; even concurrent. An array is never safe to publish to multiple threads.
  • A collection can allow or disallow null elements. An array must always permit null elements.
  • A collection is type-safe; an array is not. Because arrays "fake" covariance, ArrayStoreExceptioncan result at runtime.
  • A collection can hold a non-reifiable type (e.g. List<Class<? extends E>>or List<Optional<T>>). With an array you get compilation warnings and confusing runtime exceptions.
  • A collection has a fully fleshed-out API; an array has only set-at-index, get-at-index and length.
  • A collection can have views (unmodifiable, subList, filter...). No such luck for an array.
  • A list or set's equals, hashCodeand toStringmethods do what users expect; those methods on an array do anything butwhat you expect -- a common source of bugs.
  • Because of all the reasons above, third-party libraries like Guava won't bother adding much additional support for arrays, focusing only on collections, so there is a network effect.
  • 集合可以是可变的或不可变的。非空数组必须始终是可变的。
  • 集合可以是线程安全的;甚至并发。将数组发布到多个线程永远是不安全的。
  • 集合可以允许或禁止空元素。数组必须始终允许空元素。
  • 集合是类型安全的;数组不是。因为数组“假”协方差ArrayStoreException会在运行时产生。
  • 集合可以包含不可具体化的类型(例如List<Class<? extends E>>List<Optional<T>>)。使用数组,您会收到编译警告和令人困惑的运行时异常。
  • 集合具有完全充实的 API;一个数组只有 set-at-index、get-at-index 和 length。
  • 集合可以有视图(不可修改、子列表、过滤器...)。数组没有这样的运气。
  • 列表或集合的equals,hashCodetoString方法做用户期望的事情;数组上的这些方法做的不是你所期望的——一个常见的错误来源。
  • 由于上述所有原因,像 Guava 这样的第三方库不会费心为数组添加太多额外的支持,只关注集合,因此存在网络效应。

Object arrays will never be first-class citizens in Java.

对象数组永远不会是 Java 中的一等公民。

A few of the reasons above are covered in much greater detail in Effective Java, Second Edition, starting at page 119.

从第 119 页开始的Effective Java,第二版中更详细地介绍了上述一些原因。

So, why would you ever use object arrays?

那么,为什么要使用对象数组呢?

  • You have to interact with an API that uses them, and you can't fix that API
    • so convert to/from a Listas close to that API as you can
  • You have a reliable benchmark that shows you're actually getting better performance with them
    • but benchmarks can lie, and often do
  • I can't think of any other reasons
  • 您必须与使用它们的 API 进行交互,并且您无法修复该 API
    • 所以List尽可能接近该 API转换为/从
  • 您有一个可靠的基准测试,表明您实际上使用它们获得了更好的性能
    • 但基准可能会撒谎,而且经常会撒谎
  • 我想不出任何其他原因

回答by aioobe

It's basically a question of the desired level of abstraction.

这基本上是所需抽象级别的问题。

Most collections can be implemented in terms of arrays, but they provide many more methods on top of it for your convenience. Most collection implementations I know of for instance, can grow and shrink according to demand, or perform other "high-level" operations which basic arrays can't.

大多数集合都可以用数组来实现,但为了您的方便,它们在它之上提供了更多的方法。例如,我所知道的大多数集合实现都可以根据需求增长和缩小,或者执行基本数组不能执行的其他“高级”操作。

Suppose for instance that you're loading strings from a file. You don't know how many new-line characters the file contains, thus you don't know what size to use when allocating the array. Therefore an ArrayList is a better choice.

例如,假设您正在从文件加载字符串。您不知道文件包含多少换行符,因此您不知道分配数组时要使用的大小。因此 ArrayList 是更好的选择。

回答by hvgotcodes

The details are in the sub interfaces of Collection, like Set, List, and Map. Each of those types has semantics. A Set typically cannot contain duplicates, and has no notion of order (although some implementations do), following the mathematical concept of a Set. A List is closest to an Array. A Map has specific behavior for push and get. You push an object by its key, and you retrieve with the same key.

详细信息在Collection的子接口中,如Set、List、Map。这些类型中的每一种都有语义。遵循 Set 的数学概念,Set 通常不能包含重复项,并且没有顺序的概念(尽管某些实现有)。列表最接近数组。Map 具有特定的推送和获取行为。您通过其键推送对象,并使用相同的键检索。

There are even more details in the implementationsof each collection type. For example, any of the hash based collections (e.g. HashSet, HasMap) are based on the hashcode() method that exists on any Java object.

每个集合类型的实现中还有更多细节。例如,任何基于散列的集合(例如 HashSet、HasMap)都基于存在于任何 Java 对象上的 hashcode() 方法。

You could simulate the semantics of any collection type based of an array, but you would have to write a lot of code to do it. For example, to back a Map with an array, you would need to write a method that puts any object entered into your Map into a specific bucket in the array. You would need to handle duplicates. For an array simulating a Set, you would need to write code to not allow duplicates.

您可以模拟基于数组的任何集合类型的语义,但您必须编写大量代码才能做到这一点。例如,要使用数组支持 Map,您需要编写一个方法,将输入到 Map 中的任何对象放入数组中的特定存储桶中。您将需要处理重复项。对于模拟 Set 的数组,您需要编写不允许重复的代码。

回答by Vincent Ramdhanie

One advantage is the Iterator interface. That is all Collections implement an Iterator. An Iterator is an object that knows how to iterate over the given collection and present the programmer with a uniformed interface regardless of the underlying implementation. That is, a linked list is traversed differently from a binary tree, but the iterator hides these differences from the programmer making it easier for the programmer to use one or the other collection.

优点之一是 Iterator 接口。那就是所有集合都实现了一个迭代器。Iterator 是一个对象,它知道如何迭代给定的集合并向程序员提供统一的接口,而不管底层实现如何。也就是说,链表与二叉树的遍历方式不同,但迭代器对程序员隐藏了这些差异,使程序员更容易使用一个或另一个集合。

This also leads to the ability to use various implementations of Collections interchangeably if the client code targets the Collection interface iteself.

如果客户端代码以 Collection 接口本身为目标,这也导致可以互换地使用 Collections 的各种实现。

回答by Liv

The Collection interface is just a base interface for specialised collections -- I am not aware yet of a class that simply just implements Collection; instead classes implement specialized interfaces which extend Collection. These specialized interfaces and abstract classes provide functionality for working with sets (unique objects), growing arrays (e.g. ArrayList), key-value maps etc -- all of which you cannot do out of the box with an array. However, iterating through an array and setting/reading items from an array remains one of the fastest methods of dealing with data in Java.

Collection 接口只是专门集合的基本接口——我还不知道有一个只实现了 Collection 的类;相反,类实现了扩展 Collection 的专用接口。这些专门的接口和抽象类提供了处理集合(唯一对象)、增长数组(例如 ArrayList)、键值映射等的功能——所有这些都不能用数组开箱即用。但是,遍历数组并设置/读取数组中的项目仍然是 Java 中处理数据的最快方法之一。