轉(zhuǎn)譯自:https://examples.javacodegeeks.com
本文在已發(fā)布在GitHub(https://github.com/clxering/Technical-Articles-Collection/blob/master/9-differences-between-Array-and-ArrayList-in-Java.md)歡迎糾錯(cuò)訂正
Both array and ArrayList are two important data structures in Java and are frequently(經(jīng)常) used in Java programs. Even though ArrayList is internally(在內(nèi)部) backed by an array, knowing the difference between an array and an ArrayList in Java is critical(至關(guān)重要的) for becoming a good Java developer. If you know the similarity and differences, you can judiciously(明智而審慎地) decide when to use an array over an AraryList or vice-versa.
數(shù)組和ArrayList都是Java中非常重要的數(shù)據(jù)結(jié)構(gòu)馁害,在Java程序中經(jīng)常使用。即使ArrayList是由數(shù)組內(nèi)部支持的,了解Java中數(shù)組和ArrayList之間的區(qū)別對(duì)于成為一名優(yōu)秀的Java開(kāi)發(fā)人員至關(guān)重要。如果您知道相似性和差異性,您可以明智地決定何時(shí)以AraryList(取代)數(shù)組靡菇,或者反之亦然。
In this article, I’ll help you understand the difference. If you are coming from C or C++ background then you already know that array is one of the most useful data structure in the programming world. It offers O(1) performance for index-based search and one of the fundamental way to store data.
在本文中,我將幫助您理解其中的區(qū)別妈橄。如果你有C或c++背景,那么您已經(jīng)知道數(shù)組是編程世界中最有用的數(shù)據(jù)結(jié)構(gòu)之一翁脆。它為基于索引的搜索提供了O(1)性能眷蚓,是存儲(chǔ)數(shù)據(jù)的基本方式之一。
The ArrayList one the other hand is a class in Java Collection framework which was introduced as a dynamic array. Since an array is static in nature i.e.(即) you cannot change the size of an array once created, So, if you need an array which can resize itself then you should use the ArrayList. This is the fundamental difference between an array and an ArrayList.
ArrayList是Java集合框架中的一個(gè)類反番,作為動(dòng)態(tài)數(shù)組引入沙热。由于數(shù)組本質(zhì)上是靜態(tài)的叉钥,也就是說(shuō),一旦創(chuàng)建了數(shù)組篙贸,您就不能更改數(shù)組的大小投队,因此,如果您需要一個(gè)能夠調(diào)整自身大小的數(shù)組爵川,那么您應(yīng)該使用ArrayList敷鸦。這是數(shù)組和ArrayList的基本區(qū)別皿伺。
Array vs ArrayList in Java(Java中的數(shù)組與ArrayList)
It’s best to compare two things on some points, this will make the differences easy to understand. So let’s see what are the points on which you can compare an array with the ArrayList in Java
最好在某些點(diǎn)上比較兩件事情陆赋,這將使區(qū)別容易理解。那么舟山,讓我們看看在哪些點(diǎn)上可以將數(shù)組與Java中的ArrayList進(jìn)行比較兔甘。
1谎碍、Implementation(實(shí)現(xiàn))
The array is a native programming component or data structure but ArrayList is a class from Java Collections framework, an API. In fact, ArrayList is internally implemented using an array. Since ArrayList is a class, it holds all properties of a class e.g. you can create objects and call methods but even though the array is an object in Java it doesn’t provide any method. It just exposes a length attribute to give you the length of the array, which is constant.
數(shù)組是原生編程組件或數(shù)據(jù)結(jié)構(gòu),而ArrayList是Java Collections framework中的一個(gè)類洞焙,是一個(gè)API蟆淀。實(shí)際上,ArrayList是使用數(shù)組在內(nèi)部實(shí)現(xiàn)的澡匪。因?yàn)锳rrayList是一個(gè)類熔任,它包含一個(gè)類的所有屬性,例如唁情,你可以創(chuàng)建對(duì)象和調(diào)用方法疑苔,但即使數(shù)組是Java中的一個(gè)對(duì)象,它也不提供任何方法甸鸟。它只是公開(kāi)了一個(gè)length屬性來(lái)給你數(shù)組的長(zhǎng)度惦费,這是常量。
2抢韭、Performance(性能)
Since ArrayList is based upon array, you would assume that it provides the same performance as an array. This is true at some extent but because of extra functionality ArrayList provides there is some difference in performance between ArrayList and array, mainly in terms of memory usage and CPU time.
由于ArrayList是基于數(shù)組的薪贫,因此可以假設(shè)它提供了與數(shù)組相同的性能。這在某種程度上是正確的刻恭,但是由于ArrayList提供了額外的功能瞧省,所以ArrayList和array之間的性能有一些不同,主要是在內(nèi)存使用和CPU時(shí)間方面鳍贾。
For index-based access, both ArrayList and array provides O(1) performance but add can be O(logN) in ArrayList if adding a new element triggers resize, as it involves creating a new array in background and copying elements from the old array to new array. The memory requirement for ArrayList is also more than an array for storing the same number of objects e.g. an int[] will take less memory to store 20 int variables than an ArrayList because of object metadata overhead on both ArrayList and wrapper class.
對(duì)于基于索引的訪問(wèn)鞍匾,ArrayList和array都提供了O(1)性能,但是如果在ArrayList中添加一個(gè)新元素會(huì)觸發(fā)調(diào)整大小骑科,那么add可以是O(logN)橡淑,因?yàn)樗婕霸诤笈_(tái)創(chuàng)建一個(gè)新數(shù)組,并將元素從舊數(shù)組復(fù)制到新數(shù)組纵散。ArrayList的內(nèi)存需求也不僅僅是存儲(chǔ)相同數(shù)量對(duì)象的數(shù)組梳码,例如int[]比ArrayList存儲(chǔ)20個(gè)int變量的內(nèi)存更少,因?yàn)锳rrayList和包裝類上都有對(duì)象元數(shù)據(jù)開(kāi)銷伍掀。
3掰茶、Type Safety(類型安全)
ArrayList is type safe because it supports generics which allows the compiler to check if all objects stored in ArrayList are of the correct type. On the other hand, the array doesn’t support Generics. Which means compile time checking is not possible but array provides runtime type checking by throwing ArrayStoreException if you try to store an incorrect object into array e.g. storing a String into an int array.
ArrayList是類型安全的,因?yàn)樗С址盒兔垠裕试S編譯器檢查存儲(chǔ)在ArrayList中的所有對(duì)象是否都是正確的類型濒蒋。另一方面,數(shù)組不支持泛型把兔。這意味著編譯時(shí)檢查是不可能的沪伙,但是如果你試圖將一個(gè)不正確的對(duì)象存儲(chǔ)到數(shù)組中,例如將一個(gè)字符串存儲(chǔ)到int數(shù)組中县好,數(shù)組通過(guò)拋出ArrayStoreException(體現(xiàn)其)提供了運(yùn)行時(shí)類型檢查围橡。
4、Flexibility(靈活性)
Flexibility is the single most important thing that separates array and ArrayList. In short, ArrayList is more flexible than a plain native array because it’s dynamic. It can grow itself when needed, which is not possible with the native array. ArrayList also allows you to remove elements which are not possible with native arrays. By remove, we mean not just assigning null to the corresponding index but also copying rest of elements one index down, which ArrayList automatically does for you. You can learn more about removing objects from ArayList in my article difference between clear() and removeAll().
靈活性是區(qū)分?jǐn)?shù)組和數(shù)組列表最重要的一點(diǎn)缕贡。簡(jiǎn)而言之翁授,ArrayList比普通的原生數(shù)組更靈活,因?yàn)樗莿?dòng)態(tài)的晾咪。它可以在需要時(shí)自行增長(zhǎng)收擦,這在原生數(shù)組中是不可能的。ArrayList還允許刪除原生數(shù)組無(wú)法刪除的元素谍倦。所謂刪除塞赂,我們的意思不僅僅是給相應(yīng)的索引分配null,還包括將其他元素的一個(gè)索引復(fù)制下來(lái)昼蛀,ArrayList會(huì)自動(dòng)為您這樣做宴猾。在我的文章《clear()和removeAll()的區(qū)別》中,您可以了解關(guān)于從ArayList中刪除對(duì)象的更多信息曹洽。
5鳍置、Primitives(基本數(shù)據(jù)類型)
If you first start using ArrayList then you will realize that you cannot store primitives on ArrayList. This is a key difference between array and ArrayList because array allows storing both primitives and object. For example int[] numbers are valid but ArrayList of int is not valid. how do you deal with this problem?
如果您第一次開(kāi)始使用ArrayList,那么您將意識(shí)到不能在ArrayList上存儲(chǔ)基本數(shù)據(jù)類型送淆。這是array和ArrayList之間的一個(gè)關(guān)鍵區(qū)別税产,因?yàn)閍rray允許存儲(chǔ)基本數(shù)據(jù)類型和對(duì)象。例如int[]數(shù)字是有效的偷崩,但是ArrayList是無(wú)效的辟拷。你如何處理這個(gè)問(wèn)題?
Suppose you want to store int primitives into ArrayList than how do you that? Well, you can use the wrapper class. This is one of the reasons why wrapper class was introduced in Java. So if you want to store int 2 into ArrayList just put it, autoboxing will do the rest. Btw, this difference is not so obvious from Java 5 onwards because of auto-boxing as you will see that ArrayList.add(21) is perfectly valid and works.
假設(shè)你想把int類型存儲(chǔ)到ArrayList中阐斜,你會(huì)怎么做衫冻?您可以使用包裝器類。這是Java中引入包裝類的原因之一谒出。如果你想把int 2存儲(chǔ)到ArrayList中隅俘,只要把它放進(jìn)去邻奠,自動(dòng)裝箱就能完成剩下的。順便說(shuō)一下为居,從Java 5開(kāi)始碌宴,由于自動(dòng)裝箱的原因,這種差異就不那么明顯了蒙畴,因?yàn)槟鷮⒖吹紸rrayList.add(21)是完全有效的贰镣,并且可以工作。
6膳凝、Generics(泛型)
One more significant(重要的) difference between an ArrayList and an array is that the former supports Generic but the latter doesn’t. Since an array is of covariant type, you can use Generics with them. This means it’s not possible for a compiler to check the type-safety of an array at compile time but they can verify type-safety of Array. So how do you deal with this problem while writing a type-safe class in Java? Well, you can use the technique shown in Effective Java, where you can declare an array like E[] and later use type casting.
ArrayList和數(shù)組的另一個(gè)重要區(qū)別是前者支持泛型碑隆,而后者不支持泛型。由于數(shù)組是協(xié)變類型的蹬音,所以可以使用泛型上煤。這意味著編譯器不可能在編譯時(shí)檢查數(shù)組的類型安全性,但它們可以驗(yàn)證數(shù)組的類型安全性祟绊。那么楼入,在用Java編寫(xiě)類型安全類時(shí),如何處理這個(gè)問(wèn)題呢牧抽?您可以使用Effective Java中所示的技術(shù)嘉熊,可以聲明一個(gè)像E[]這樣的數(shù)組,然后使用類型轉(zhuǎn)換扬舒。
7阐肤、Iteration(迭代)
ArrayList provides more ways for iteration i.e. accessing all elements one by one than an array. You can only use loop e.g. for, while, enhanced for loop and do-while to iterate over an array but you can also use Iterator and ListIterator class to iterate over ArrayList. See here to learn different ways to iterate over ArrayList in Java.
ArrayList相比數(shù)組而言為迭代,即逐個(gè)訪問(wèn)所有元素讲坎,提供了更多的方法孕惜。你只能使用for循環(huán)、 while循環(huán)晨炕、增強(qiáng)for循環(huán)和do-while來(lái)迭代數(shù)組衫画,但你也可以使用Iterator和ListIterator類來(lái)迭代ArrayList。請(qǐng)參閱此處以了解在Java中迭代ArrayList的不同方法瓮栗。
8削罩、Supported Operations(運(yùn)算符支持)
Since ArrayList is backed by an array internally, it exposes(揭露) the operation which is possible with an array but given its dynamic nature it also added operation which is not possible with native array e.g. you can store elements in both array and ArrayList, but only ArrayList allows you to remove an element. Though you can simulate that with an array by assigning null to respective index, it won’t be like remove unless you also move all element above that index in the array to one level down.
因?yàn)锳rrayList是由數(shù)組內(nèi)部支持的,所以它公開(kāi)了使用數(shù)組可以實(shí)現(xiàn)的操作费奸,但考慮到它的動(dòng)態(tài)特性弥激,它還添加了使用原生數(shù)組不可能實(shí)現(xiàn)的操作,例如愿阐,您可以在數(shù)組和ArrayList中存儲(chǔ)元素微服,但只有ArrayList允許您刪除元素。雖然您可以通過(guò)將null賦值給相應(yīng)的索引來(lái)模擬這個(gè)過(guò)程缨历,但是它不會(huì)像remove那樣以蕴,除非您還將數(shù)組中位于該索引之上的所有元素向下移動(dòng)一層糙麦。
Both ArrayList and array provide ways to retrieve an element e.g. get() method of ArrayList uses an index to get an element from array e.g. version[0] will return the first element.
ArrayList和array都提供了檢索元素的方法,例如ArrayList的get()方法使用索引從數(shù)組中獲取元素丛肮,例如version [0]將返回第一個(gè)元素喳资。
ArrayList also provides an operation to clear and reuse(重chong用) e.g. clear() and removeAll(), the array doesn’t provide that but you can loop over Array and assign each index null to simulate that.
ArrayList還提供了一個(gè)清除和重用的操作,例如clear()和removeAll()腾供,數(shù)組沒(méi)有提供這個(gè)功能,但是你可以用循環(huán)數(shù)組鲜滩,為每個(gè)索引分配null的方式來(lái)模擬它伴鳖。
9、Size() vs length(Size()方法與length屬性)
Array only provides a length attribute which tells you the number of slots in the array i.e. how many elements it can store, it doesn’t provide you any method to find out how many are filled and how many slots are empty i.e. the current number of elements. While ArrayList does provides a size() method which tells a number of objects stored in ArrayList at a given point of time. The size() is always different than length, which is also the capacity of ArrayList. If you want to know more, I suggest you read the difference between size() and length in ArrayList article.
數(shù)組只提供一個(gè)length屬性徙硅,它告訴你數(shù)組中的槽數(shù)榜聂,也就是它可以存儲(chǔ)多少個(gè)元素,它不提供任何方法來(lái)找出有多少個(gè)被填充嗓蘑,有多少個(gè)槽是空的须肆,也就是當(dāng)前元素的數(shù)量。雖然ArrayList提供了一個(gè)size()方法桩皿,它告訴在給定時(shí)間點(diǎn)存儲(chǔ)在ArrayList中的許多對(duì)象豌汇。size()總是與length不同,length也是ArrayList的容量泄隔。如果您想了解更多拒贱,我建議您閱讀ArrayList文章中的size()和length之間的區(qū)別。
10佛嬉、Dimension(維度)
Another significant(重要的) difference between an array and an ArrayList is that array can be multi-dimensional e.g. you can have a two-dimensional array or a three-dimensional array, which makes it a really special data structure to represent matrices and 2D terrains. On the other hand, ArrayList doesn’t allow you to specify dimension. See this tutorial learn more about how to use a multi-dimensional array in Java.
數(shù)組和ArrayList的另一個(gè)重要區(qū)別是逻澳,數(shù)組可以是多維的,例如暖呕,你可以有一個(gè)二維數(shù)組或三維數(shù)組斜做,這使得它可以成為一種非常特殊的數(shù)據(jù)結(jié)構(gòu)來(lái)表示矩陣和二維地形。另一方面湾揽,ArrayList不允許指定維度瓤逼。請(qǐng)參閱本教程,了解如何在Java中使用多維數(shù)組钝腺。
Here is the nice slide highlighting all important difference between Array and ArrayList in Java:
下面這張幻燈片(注:已將圖片內(nèi)容轉(zhuǎn)為文字)突出了Java中數(shù)組和ArrayList的所有重要區(qū)別:
Difference between array vs ArrayList in Java(Java中數(shù)組與ArrayList的區(qū)別)
1抛姑、An array is static, you cannot change it's length once created, but ArrayList is dynamic, it can grow to accommodate more elements.
數(shù)組是靜態(tài)的,一旦創(chuàng)建就不能改變它的長(zhǎng)度艳狐,但是ArrayList是動(dòng)態(tài)的定硝,它可以增長(zhǎng)以適應(yīng)更多的元素。
2毫目、The array doesn't support generics, hence they are not type-safe but ArrayList support Generics, hence they provide compile time type-safety.
數(shù)組不支持泛型蔬啡,因此它們不是類型安全的诲侮,但是ArrayList支持泛型,因此它們提供編譯時(shí)類型安全箱蟆。
3沟绪、Array takes less memory than Arrayist for storing same number of elements or objects.
在存儲(chǔ)相同數(shù)量的元素或?qū)ο髸r(shí),數(shù)組比Arrayist占用更少的內(nèi)存空猜。
4绽慈、ArrayList allows you to remove element, but array doesn't provide such methods.
ArrayList允許刪除元素,但數(shù)組不提供這樣的方法辈毯。
5坝疼、Array can accommodate both primitive and objects, but Arraylist can only accommodate objects.
數(shù)組可以同時(shí)容納基礎(chǔ)數(shù)據(jù)類型和對(duì)象,但Arraylist只能容納對(duì)象谆沃。(注:本文第5點(diǎn)提到了钝凶,從Java 5開(kāi)始Arraylist也能容納基礎(chǔ)數(shù)據(jù)類型)
6、Array can be multi-dimensional but ArrayList is always one dimensional.
數(shù)組可以是多維的唁影,但ArrayList總是一維的耕陷。(注:應(yīng)該說(shuō)ArrayList默認(rèn)是一維的,如果每個(gè)元素也是一個(gè)ArrayList据沈,可以間接實(shí)現(xiàn)多維)
7哟沫、Array provides length attribute and ArrayList provides size() but both are different, length is capacity, while size() return number of elements.
數(shù)組提供length屬性,ArrayList提供size()锌介,但兩者不同南用,length是容量,size()返回元素?cái)?shù)量掏湾。
Similarities between Array and ArrayList(數(shù)組和數(shù)組列表的相似性)
So far you have seen the difference between an ArrayList and an array, now let’s concentrate(關(guān)注) on some of the similarities. Since ArrayList internally uses array, it’s bound to have lot of similarities as seen below:
到目前為止裹虫,您已經(jīng)看到了ArrayList和數(shù)組之間的區(qū)別,現(xiàn)在讓我們關(guān)注一些相似之處融击。由于ArrayList內(nèi)部使用數(shù)組筑公,兩者肯定有很多相似之處,如下所示:
1尊浪、Data Structure(數(shù)據(jù)結(jié)構(gòu))
Both allow you to store objects in Java and both are an index-based data structure which provides O(1) performance to retrieve an element, but search without an index is still log(N) if your array is sorted and you use binary search algorithm.
這兩種方法都允許在Java中存儲(chǔ)對(duì)象匣屡,并且都是基于索引的數(shù)據(jù)結(jié)構(gòu),它提供了O(1)性能來(lái)檢索元素拇涤,但是如果數(shù)組是有序的捣作,并且使用二進(jìn)制搜索算法,那么沒(méi)有索引的搜索仍然是log(N)鹅士。
2券躁、Order(有序性)
Both array and ArrayList maintain(維護(hù)) order on which elements are added into them.
數(shù)組和ArrayList的元素順序就是添加時(shí)的順序。
3、Search(搜索)
You can search for an element using an index, that’s O(1) otherwise you can use linear search if your array is not sorted, which takes around O(n) time or you can use binary search after sorting an array in Java, this is sorting + O(logN).
你可以用索引來(lái)搜索一個(gè)元素也拜,它是O(1)的以舒,如果你的數(shù)組沒(méi)有排序,你可以用線性搜索慢哈,這需要大約O(n)的時(shí)間蔓钟,或者你可以用二進(jìn)制搜索,在Java中對(duì)一個(gè)數(shù)組排序后卵贱,這是排序+ O(logN)滥沫。
4、Null values(空值)
Both array and ArrayList allow null values but remember only object array allows null primitive array doesn’t they store the default value of primitive type e.g. zero for int and false for boolean.
數(shù)組和ArrayList都允許空值键俱,但記住只有對(duì)象數(shù)組允許空基元數(shù)組佣谐,它們不存儲(chǔ)基元類型的默認(rèn)值,例如方妖,0表示int, false表示boolean。
5罚攀、Duplicates(重復(fù))
Both array and ArrayList allow duplicates. It’s also one of the common array based coding questions to write a program to find out duplicates from an array in place.
數(shù)組和ArrayList都允許(元素)重復(fù)党觅。它也是一個(gè)常見(jiàn)的基于數(shù)組的編碼問(wèn)題,即編寫(xiě)一個(gè)程序從一個(gè)數(shù)組中找出(元素)副本斋泄。
6杯瞻、Performance(性能)
ArrayList mimic array’s performance e.g. O(1) access if you know the index but it has additional memory overhead because it’s an object and also holds additional data to automatic resize the ArrayList.
?
ArrayList模擬數(shù)組的性能,如O(1)訪問(wèn)炫掐,如果你知道索引魁莉,但是它有額外的內(nèi)存開(kāi)銷,因?yàn)樗且粋€(gè)對(duì)象募胃,而且還包含額外的數(shù)據(jù)來(lái)自動(dòng)調(diào)整ArrayList的大小旗唁。
7、Zero-based Index(從零開(kāi)始的索引)
Both array and ArrayList have zero-based index i.e. first element starts at zeroth index.
數(shù)組和ArrayList都有從零開(kāi)始的索引痹束,即第一個(gè)元素從第0個(gè)索引開(kāi)始检疫。
The most important difference you should remember is that array is static in nature i.e. you cannot change their size once created but ArrayList is a dynamic array, which can resize itself if a number of elements in the ArrayList are more than the resize threshold. Based upon this difference, you should use an array as a data structure to store objects if you know the size in advance and sure it’s not going to change, if you are unsure then just use the ArrayList.
你應(yīng)該記住的最重要的區(qū)別是數(shù)組本質(zhì)上是靜態(tài)的,也就是說(shuō)你不能改變它們的大小祷嘶,但是ArrayList是一個(gè)動(dòng)態(tài)數(shù)組屎媳,如果ArrayList中的一些元素超過(guò)了閾值,它可以調(diào)整自己的大小论巍≈蛞辏基于這種差異,如果您事先知道對(duì)象的大小并且確定不會(huì)改變對(duì)象的大小嘉汰,那么您應(yīng)該使用數(shù)組作為數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)對(duì)象丹禀,如果您不確定,那么就使用ArrayList。