实现
数组是基础编程组件或数据结构,但是 ArrayList
是 Java Collections
框架(一个API)中的类,实际上,ArrayList
是使用 Java 中的数组在内部实现的,因为 ArrayList
是一个类,所以它拥有类的所有属性,例如:您可以创建对象和调用方法,但是 Array
是 Java 中的对象,它不提供任何方法,它只提供一个共公的 length
属性来提供数组的长度,并且数组的长度是固定不变的
性能
由于 ArrayList
基于数组,因此一定程度上两者的性能相当,在某种程度上确实如此,但是由于 ArrayList
提供了额外的功能,所以 ArrayList
和数组的性能存在一些差异,主要是在内存使用和CPU时间方面,对基于索引的访问,ArrayList
和 Array
均提供 O(1)
性能,但是如果添加新元素会触发调整大小,则添加在 ArrayList
中可以为O(logN)
,因为这涉及在后台创建新数组并从旧数组中复制元素到新的数组。ArrayList 中的内存需要也不仅仅是用于存储相同数量对象的数组,例如 int[]
与 ArrayList
相比,int[] 存储 20 个 int
变量所需的内存更少,这是因为 ArrayList
和 wrapper
类的对象元数据开销很大
类型安全性
ArrayList
是类型安全的,因为它支持泛型,泛型允许编译器检查 ArrayList
中存储的所有对象的类型正确正确。替换,但数组不支持 Java 中的 Generic。这意味着无法进行编译时检查,但是如果您尝试将不正确的对象存储到数组中(例如:将字符串存储到 int
数组中),则 Array
通过引发 ArrayStoreException
来提供运行时类型检查。
通用
简而言之,ArrayList
比普通的数组分散更灵活,因为它是动态的。它可以在需要时自行增长,而 Array
布局则无法实现。ArrayList
中还允许您删除 Array
无法实现的元素。通过删除,我们的意思不仅是将零分配给相应的索引,还意味着将其余元素向下复制一个索引,而 ArrayList
中会自动为您完成。
基础数据类型
如果您首先开始使用 ArrayList
,那么您将无法在 ArrayList
上存储基元。这是 Array
和 ArrayList
之间的关键区别,因为可以提供存储基本类型和对象。例如,int[]
数字有效,但 int 的 ArrayList
无效。您如何处理这个问题?假设您想将 int
原语存储到 ArrayList
中,那又如何呢?好了,在 Java 中您可以使用包装器类。因此,如果您只想将 int 2
存储到 ArrayList 中,其余的操作将由自动装箱完成。顺便说一句,由于自动装箱,这种差异从 Java 5 开始并不明显,因为您会看到 ArrayList.add(21)
完全有效并且可以正常工作。
泛型
ArrayList
和 Array
的另一个重要区别是,前者支持Generic,但后者不支持Generic。由于是协变类型的,因此可以将泛型与它们一起使用。这意味着编译器不可能在编译时检查数组的类型安全性,但他们可以验证 Array
的类型安全性。
迭代行
ArrayList
提供了更多的迭代方式,即 Array
只能通过循环索引一一访问所有元素。例如:针对循环的增强和 do-while
来遍历数组,但 ArrayList
还可以使用 Iterator
和 ListIterator
类来遍历。
支持的操作
由于 ArrayList
在内部由数组支持,因此它公开了 Array
可能执行的操作,但是鉴于其动态特性,它还没有添加 Array
无法执行的操作,例如,您可以将元素存储在 Array
和 ArrayList
中,但是只有 ArrayList
允许您删除元素。虽然您可以通过分配 null
使用数组来模拟到相应的索引,除非将多个中间该索引上方的所有元素都向下移动一级,否则它不会像删除。
ArrayList
和 Array
都提供了检索元素的方法,例如 ArrayList
的 get()
方法使用索引从数组中获取元素,例如,ArrayList.get(0)
将返回第一个元素。ArrayList
还提供了清除和重用的操作,例如 clear()
和 removeAll()
,Array
不提供该操作,但是您可以循环遍历 Array
并为每个索引分配 null
以模拟它。
size()
与length
数组仅提供一个 length
属性,该属性告诉您数组中的插槽数,即可以存储多少个元素,它不提供任何方法来找出已填充的元素数和多少个插槽为空,即元素。尽管 ArrayList
确实提供了 size()
方法,该方法告诉给定时间点存储在 ArrayList 中的对象数量。size()
始终与 length
不同,这也是 ArrayList
的容量。
维度
数组和数组列表之间的另一个显着区别是,数组可以是多维的,例如,您可以具有二维数组或三维数组,这可以表示矩阵和2D地形的非常特殊的数据结构。
数据结构
两者都允许您将对象存储在Java中,并且彼此都是基于索引的数据结构,可提供O(1)
性能来检索元素,但是,如果对进行了排序和使用了二进制搜索算法,则没有索引的搜索仍然是LOG(N)
顺序
Array
和 ArrayList
都保持将元素添加到其中的顺序。
搜索
您可以使用索引搜索元素,即O(1)
,否则,如果未对片段进行排序,则可以使用线性搜索,这大约需要O(n)
的时间,也可以在对进行进行排序后使用二进制搜索Java,这是排序+ O(logN)
空值
Array
和 ArrayList
允许空值,但请记住只有对象数组允许其存储为空,原始类型不能为空,原始类型为使用默认值。例如:int
类型的 0
与 boolean
类型的 false
复制
Array
和 ArrayList
都允许复制
性能
ArrayList
模拟数组的性能,例如,如果您知道索引,则可以进行 O(1)
访问,但是它具有额外的内存开销,因为它是一个对象,并且还拥有其他数据以自动调整 ArrayList
的大小。
从零开始的索引
Array
和 ArrayList
都有从零开始的索引,即第一个元素从第零个索引开始。
这就是 Java 中数组与 ArrayList 之间真正的区别的全部
您应该记住的最重要的区别是:
Array
本质上是静态的,即创建后就无法更改其大小
ArrayList
是动态数组,如果 ArrayList
中的元素数大于其阈值,则可以调整自身大小。
基于这种差异:
如果预先知道大小并确定它不会改变,则应该使用 Array
如果不确定,则只需使用 ArrayList