詳解Java中Array和ArrayList的比較和轉(zhuǎn)換
1. 介紹
在 Java
中, ArrayList
是集合框架的一部分,是可調(diào)整數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)。這一位意味著 arraylist
內(nèi)部維護(hù)了一個(gè)需要?jiǎng)討B(tài)增長或者收縮的數(shù)組。
1.1 Java Arrays
array
是一個(gè)固定大小的數(shù)據(jù)結(jié)構(gòu),在連續(xù)的內(nèi)存空間中存放相同類型的數(shù)據(jù)。 array
中的每個(gè)元素通過索引或者位置識(shí)別,首個(gè)元素從 0
開始。
Java
語言中的 arrays
跟其他語言中的數(shù)組類似。通常,它們有下面的特性:
Arrays
通常存儲(chǔ)同種數(shù)據(jù)類型的元素。數(shù)據(jù)的類型在初始化的時(shí)候就已經(jīng)定義好。- 一個(gè)整數(shù)類型數(shù)組只能存放整數(shù)。
Java
的編譯器不允許在整數(shù)類型的數(shù)組中存放字符串?dāng)?shù)據(jù)。 - 數(shù)組中的每個(gè)元素只能通過索引獲取。沒有其他獲取數(shù)組元素的方法。
- 數(shù)組的大小通常是固定的并且不能更改。要存放比數(shù)組大小更多的元素,我們必須創(chuàng)建新的數(shù)組,然后將舊數(shù)組數(shù)據(jù)拷貝到新數(shù)組。當(dāng)我們嘗試添加超過數(shù)組大小的元素,將會(huì)拋出 ** ArrayIndexOutOfBoundsException** 錯(cuò)誤。
比如,以下數(shù)組是其在內(nèi)部存儲(chǔ)器的表現(xiàn):
int [] a = new int[5]; a[0] = 1; a[1] = 2; a[2] = 4; a[3] = 8; a[4] = 16;
Arrays
有一個(gè)固定的長度,這就是說一旦數(shù)組被創(chuàng)建,數(shù)組大小不可以被改變。數(shù)組中元素的獲取通過響應(yīng)的索引獲取。
for(int i = 0; i < a.length; i++) { System.out.println(a[i]); }
1.2 Java ArrayList
ArrayList
類是 Java
集合框架的一部分,用來實(shí)現(xiàn) List
接口。不像 arrays
, ArrayLists
伴隨著元素的添加或者移除來增長或者縮小。
可以在 arraylist
中存放多種類型的元素,但是通常不推薦,因?yàn)樵谶\(yùn)行時(shí)獲取數(shù)組元素時(shí)可能會(huì)引發(fā) ClassCastException 異常。為了確保類型安全,泛型 generics
被用來聲明存儲(chǔ)在 arraylist
中的元素類型。
List<Integer> arraylist = new ArrayList<>(); arraylist.add(1); // allowed // arraylist.add("one"); // NOT allowed
除了可以使用 for
循環(huán)來順序獲取之外, arraylist
也允許使用迭代器來獲取,比如 ListIterator。當(dāng)我們使用迭代器并使用迭代器修改集合時(shí),不會(huì)拋出 ConcurrentModificationException 異常。
List<Integer> arraylist = new ArrayList<>(); arraylist.add(1); arraylist.add(2); arraylist.add(3); // 1 - using foreach loop arraylist.forEach(System.out::println) // 2 - using iterator ListIterator<Integer> listIterator = arraylist.listIterator(); while(listIterator.hasNext()) { System.out.println(listiterator.next()); }
2. Java 中 Array 和 ArrayList 的不同
下面的表格是 arrays
和 arraylists
的比較總結(jié)。比較這兩個(gè)數(shù)據(jù)機(jī)構(gòu),基于它們的性能,使用和場(chǎng)景。
特性 | Arrays | ArrayLists |
---|---|---|
固定大小和動(dòng)態(tài)大小 | 在初始化的時(shí)候就分配固定大小 | 動(dòng)態(tài)調(diào)整大小,隨著元素的添加或刪除而變化 |
內(nèi)存管理和效率 | 如果數(shù)組大小超出了實(shí)際需要的個(gè)數(shù),固定大小可能導(dǎo)致內(nèi)存浪費(fèi) | 動(dòng)態(tài)調(diào)整大小會(huì)帶來輕微的性能開銷,但是可以優(yōu)化內(nèi)存使用 |
語法和使用難易 | 初始化,增加,移除和更新操作語法很直白 | 使用 Collections API 方法更直觀、更方便工作 |
性能 | 對(duì)于讀/寫操作, arrays 通常很快,因?yàn)樗侵苯邮褂迷厮饕@取。對(duì)于需要調(diào)整大小的寫操作, arraylists 性能優(yōu)于 array | 除了需要調(diào)整大小的寫操作,其他的操作 arraylists 表現(xiàn)得比 arrays 差 |
類型安全 | Arrays 具有有限的類型安全性,并允許任何類型的元素存儲(chǔ)在同個(gè)數(shù)組中 | 通過泛型, ArrayLists 提供更好的類型安全性,確保特定類型的元素被存儲(chǔ) |
最佳使用場(chǎng)景 | 當(dāng)需要固定大小的集合并且看中內(nèi)存效率,則使用 array | ArrayList 最適合用于小型的集合,其中方便性微小且可忽略的性能提升 |
3. Array 轉(zhuǎn)換為 ArrayList
將 Array
轉(zhuǎn)換為 ArrayList
最直接的方法是使用 Arrays.asList()
方法,該方法創(chuàng)建了數(shù)組的列表視圖,然后我們使用 ArrayList
構(gòu)造函數(shù)創(chuàng)建一個(gè)新的 ArrayList
。這有效地將數(shù)組轉(zhuǎn)換為 ArrayList
。
String[] array = {"apple", "banana", "cherry"}; ArrayList<String> arrayList = new ArrayList<>(Arrays.asList(array));
另外,我們也可以使用 Java 8 streams 來迭代數(shù)組元素,并將它們收集在一個(gè)新的 ArrayList
中。它給我們提供了在將元素收集到列表前對(duì)數(shù)組的每個(gè)元素執(zhí)行額外操作的機(jī)會(huì)。
ArrayList<String> arrayList = Arrays.stream(array) // additional actions .collect(Collectors.toCollection(ArrayList::new));
4. ArrayList 轉(zhuǎn)換為 Array
最簡單的轉(zhuǎn)換一個(gè) arraylist
為 array
方案是使用 ArrayList.toArray() 方法,該方法返回一個(gè)包含列表中所有元素的數(shù)組,并且元素順序正確。 toArray()
返回 Object[]
類型的數(shù)組,所以你需要提供你想要的數(shù)組類型作為參數(shù)。
新數(shù)組的大小是由 ArrayList
大小決定的。
ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("apple"); arrayList.add("banana"); arrayList.add("cherry"); String[] array = arrayList.toArray(new String[arrayList.size()]);
5. 最佳實(shí)踐和推薦
ArrayLists
和 arrays
都有相同的目的和各自的優(yōu)點(diǎn)。以下建議是有助于我們縮小范圍并選擇適合我們應(yīng)用程序的正確數(shù)據(jù)結(jié)構(gòu)。
5.1 頻繁更改大小操作
因?yàn)樘厥獾男枨?,如果?shù)組需要頻繁更改大小,建議使用 ArrayList
。 調(diào)整大小操作的內(nèi)部處理消除了應(yīng)用程序代碼的復(fù)雜度,并提供了和手動(dòng)修改相似的性能增益。
5.2 性能提升的可量化
如果性能提升不是很重要,那么還是推薦使用 arraylists
。 ArrayLists
避免了復(fù)雜性,并且讓代碼可讀性更高,且性能在處理小的集合跟 array
相似。
衡量性能增益的最佳方式是使用諸如 JMH
之類的工具進(jìn)行測(cè)量。
5.3 原始類型 VS 包裝對(duì)象
Array
可以直接處理原始類型,而 arraylists
則與對(duì)象(即包裝類)一起使用。 如果在應(yīng)用程序中處理它們時(shí)需要不斷進(jìn)行兩種類型的轉(zhuǎn)換,最好使用 arrays
,因?yàn)樗鼈儠?huì)消除不必要的類型轉(zhuǎn)換來簡化代碼,并因此帶來輕微的性能提升。
int[] array = new int[10]; //Creating arraylist for 'int' type is not possible. We must create arraylist of type 'Integer' ArrayList<Integer> arraylist = new ArrayList<>();
5.4 與其他集合類型互操
ArrayList
是 Java
集合框架的一部分,所以和其他類型(比如: Map
, Set
)的操作是無縫的。使用 arrays
將會(huì)產(chǎn)生轉(zhuǎn)換成其他類型不必要的額外步驟。
使用 arraylist
將減少這類的轉(zhuǎn)換,因此代碼可讀性更高且更簡潔。
6. 總結(jié)
總之,Java
開發(fā)的最佳實(shí)踐通常推薦使用 ArrayLists
和其他內(nèi)置的集合類,因?yàn)樗鼈兏`活,并且相比中等大小的集合性能相似。
然而,arrays
也有實(shí)用的場(chǎng)景,特別是在意性能和內(nèi)存效率的情況。
以上就是詳解Java中Array和ArrayList的比較和轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于Java Array和ArrayList的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java?C++題解leetcode字符串輪轉(zhuǎn)KMP算法詳解
這篇文章主要為大家介紹了Java?C++題解leetcode字符串輪轉(zhuǎn)KMP算法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09自己動(dòng)手寫一個(gè)java版簡單云相冊(cè)
這篇文章主要為大家分享了自己動(dòng)手寫的一個(gè)java版簡單云相冊(cè),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07uploadify java實(shí)現(xiàn)多文件上傳和預(yù)覽
這篇文章主要為大家詳細(xì)介紹了java結(jié)合uploadify實(shí)現(xiàn)多文件上傳和預(yù)覽的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10springboot整合JSR303參數(shù)校驗(yàn)與全局異常處理的方法
JSR-303 是 JAVA EE 6 中的一項(xiàng)子規(guī)范,叫做 Bean Validation,官方參考實(shí)現(xiàn)是Hibernate Validator,這篇文章主要介紹了springboot整合JSR303參數(shù)校驗(yàn)與全局異常處理,需要的朋友可以參考下2022-09-09詳解Spring Cloud Eureka多網(wǎng)卡配置總結(jié)
本篇文章主要介紹了詳解Spring Cloud Eureka多網(wǎng)卡配置總結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04java 中序列化與readResolve()方法的實(shí)例詳解
這篇文章主要介紹了java 中序列化與readResolve()方法的實(shí)例詳解的相關(guān)資料,這里提供實(shí)例幫助大家理解這部分知識(shí),需要的朋友可以參考下2017-08-08Spring中如何獲取request的方法匯總及其線程安全性分析
這篇文章主要給大家介紹了關(guān)于Spring中如何獲取request的方法匯總及其線程安全性分析的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-04-04Java 常見異常(Runtime Exception )詳細(xì)介紹并總結(jié)
這篇文章主要介紹了Java 常見異常(Runtime Exception )詳細(xì)介紹并相關(guān)資料,大家在開發(fā)Java 應(yīng)用軟件的時(shí)候經(jīng)常會(huì)遇到各種異常這里幫大家整理了一部分,并解釋如何解決,需要的朋友可以參考下2016-10-10java中快速創(chuàng)建帶初始值的List和Map實(shí)例
下面小編就為大家?guī)硪黄猨ava中快速創(chuàng)建帶初始值的List和Map實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10