【Java】 Array 与 ArrayList 的区别

本文参考:http://blog.qianlicao.cn/translate/2016/03/09/array-vs-arraylist/

感觉这篇文章很好,基本数据类型总结:http://www.cnblogs.com/doit8791/archive/2012/05/25/2517448.html

最大不同之处:Array是静态的,其一旦创建大小是不可改变的;ArrayList是Java集合框架类的一员,可以称它为一个动态数组如果事先知道数组的长度,并且确定它的大小不会改变,应该使用Array,否则使用ArrayList

不同点:

1) Implementation 实现

array 是本地的程序设计组件或者数据结构,但是ArrayList是一个来自Java集合类的类,一个接口 (Application programming interface). 实际上,ArrayList 在Java上,它的内部是由一个array实现的. 既然ArrayList是一个类,所以它持有了所有类的属性.例如,你可以创建对象,可以调用方法,但array并不提供任何方法. 它仅仅暴露了一个常量的长度来表示当前数组的长度.

2) Performance 性能

ArrayList是基于array,但是在一些额外功能性的ArrayList上性能还是和array 存在一定差别, 主要是内存的使用和CPU 耗时. 在索引上,ArrayListarray都能提供O(1)的时间复杂度,但是在添加item的时候如果出发resize,ArrayList可能会是O(logN)的时间复杂度,因为它包含了创建一个新的array 和将老的array的数据拷贝到新的array里. 在存储相同数量的对象时,ArrayList所需要的内存也是比array大的. 例如一个int[] 的数组会比ArrayList节省20个int 变量的大小,因为对象的基本数据会在ArrayList和包装类上进行开销.

3) Type Safety 类型安全

ArrayList 是类型安全的,因为它支持泛型(Generics) 允许编译器检查 ArrayList 里所包含的对象是否是正确的类型.然而, array 并不支持泛型.这代表在编译时期检查array 所保存对象的类型是不可能的,但是array 通过抛出 ArrayStoreException 异常的方式来进行运行时的类型检查如果你存储了一个错误类型的对象,例如,存储一个String 到 int array 里。???这里不是很理解,int[]数组中放String类型值时会有编译错误提示呀】

4) Flexibility 灵活性

灵活性是区分array 和 ArrayList最重要的一个东西,简单来说,ArrayList比简单的array要灵活的多,因为 ArrayList 是动态的,它可以在需要的时候扩大自己的内存,这是一个 array 不可能做到的.ArrayList 也允许你删除元素, 这在array上也是不可能的.通过删除,我的意思并不是将null置于对应的index里,而是将所删除元素的后面所有元素的index都往前移动一位,这些都是ArrayList自动为我们做的.你可以从我的文章里学到更多关于从ArrayList里删除对象difference between clear() and removeAll()

5) Primitives 基本类型

如果你第一次开始使用Arraylis,你会发现,你不能保存基本类型到ArrayList里,这是arrayArrayList一个关键的不同,因为array既可以保存对象也可以保存基本类型.例如.int[]数组是合法的,但是一个int型的ArrayList是不合法的.

ArrayList list = new ArrayList<>();是错误的!!! 会报错:Syntax error on token "int", Dimensions expected after this token

 如何解决这个问题呢? 假设你想存储int类型到ArrayList里,你会怎么做呢? 是的,你可以用封装类,ArrayList<Integer> list = new ArrayList<>();

从java5开始,这个区别越来越不明显了,因为通过自动封装你会发现``ArrayList.add(21)是非常合法并且运行正常.

6) Generics 泛型

ArrayListarray之间的另外一个重要的区别就是前者能够显示的支持泛型,后者不行.由于数组是协变性的,所以你可以在array上使用泛型(Since an array is of covariant type, you can use Generics with them).这个表示编译器不可能检查array的类型安全,但是可以校验类型安全.当你要写一个类型安全的类的时候如何解决这个问题呢?通过申明一个类似于E[]的数组,然后后期进行类型转换.

7) Iteration 迭代

ArrayList 提供比array更多的方式来迭代一个接一个的访问所有的元素.可以通过for,while等循环来遍历array,但是你可以通过Iterator 和ListIterator类来遍历ArrayList.看这里来了解更多的遍历ArrayList的方式.

8) Supported Operations 支持的操作

由于ArrayList的内部是由一个array支撑着,所以它提供了能够在array可能支持的操作,并且还提供了它动态的属性.它也支持添加操作,这是在array上不可能的.你可以同时在arrayArrayList上存储元素,但是仅ArrayList允许你删除元素.然而你可以通过模拟将null赋值到对应的index里来模拟删除.这个模拟不会像是删除,除非你同时将所删除元素对应的索引(index)移动到下一级

ArrayListarray头提供取元素的方法.例如ArrayList用索引通过get()方法来获取一个元素, version[0]将会返回array的第一个元素.ArrayList也提供一个方法来清空和重用例如,clear() 和 removeAll().array并不提供那些方发,但是你可以通过循环这个数组来将null赋值到所有的元素里来模拟ArrayListremoveAll()

9) Size() vs length 大小 vs 长度

array 仅仅提供一个length 属性来告诉你array里有多少个插槽,例如可以存储多少个元素.它没有提供任何方法来告诉你哪些插槽是满的,哪些是空的.例如,当前元素的个数.但是ArrayList提供一个size()方法来告诉你当前时间点ArrayList存储了多少个元素.size() 总是和length不同的,它也是ArrayList的容量.如果你想知道更多关于这个的知识,我建议你阅读这篇文章文章array length vs ArrayList Size in Java

10) Dimension 维度

ArrayListarray的另外一个重要的区别就是array可以使多维度的.例如,你可以设置一个二维数组或者三维数组.可以使你创在一个特殊的数据结构来代表矩阵或者2D形式(terrains),另一方面,ArrayList并不支持允许你指定维度.请参见这个指导来学习更多关于如何在Java里使用多维度的数组.

这里是列出了所有ArrayListarray的重要区别

相同点

1) Data Structure 数据结构

两者都允许你存数对象,并且所有的都是基于index的数据结构,提供O(1)的复杂度来获取一个元素,但是如果通过二分查找来查询某个元素依旧需要log(N)的复杂度.

2) Order 顺序

Both array and ArrayList maintains order on which elements are added into them. 

Array和ArrayList中元素顺序按添加顺序排列。可System.out.println()查看。

3) Search 查找

你可以通过index来查找一个元素,这个是O(1)的时间复杂度,除此之外如果你的array不是排好序的数组你可以用线性的查找,这个将消耗大约O(n)的时间复杂度,或者你可以将数组排序后使用二分查找,这个将消耗排序的时间复杂度加上O(logN)

4) Null values 空值

array 和 ArrayList都允许存储null值,但请记住只有object的array可以这样,基本类型的数组会存储他们的默认值,例如int型的数组默认存储0,boolean的数组默认存储false.

5) Duplicates 重复

array和Arraylis都允许存储重复的值。

6) Performance 性能

ArrayList模仿array的性能,例如O(1)复杂度的访问元素如果你知道这个元素的index,但是ArrayList会消耗更多的内存,因为它是存储的对象,并且持有了而外的数据来自动更改ArrayList的长度.

7) Zero-based Index

index都是从0开始。


你可能感兴趣的:(java)