Java?ArrayList集合之解鎖數(shù)據(jù)存儲(chǔ)新姿勢
一、引言
在 Java 編程中,我們經(jīng)常需要處理多個(gè)元素的數(shù)據(jù)。數(shù)組是一種基本的數(shù)據(jù)存儲(chǔ)方式,但它存在一些局限性,比如長度固定。為了更靈活地處理數(shù)據(jù),Java 提供了集合框架,它能根據(jù)元素的添加或刪除自動(dòng)調(diào)整大小,并且提供了豐富的操作方法。
二、為什么需要集合
2.1 數(shù)組的弊端
當(dāng)我們想要同時(shí)存儲(chǔ)多個(gè)元素時(shí),首先會(huì)想到數(shù)組。例如:
int[] arr = new int[3];
數(shù)組的優(yōu)點(diǎn)是可以快速訪問元素,通過索引可以直接定位到元素。然而,數(shù)組的長度是固定的。一旦數(shù)組創(chuàng)建,其長度就不能再改變。如果我們需要存儲(chǔ)更多的元素,就需要?jiǎng)?chuàng)建一個(gè)新的數(shù)組,并將原數(shù)組的元素復(fù)制過去,這無疑增加了代碼的復(fù)雜性和性能開銷。
2.2 集合的優(yōu)勢
集合的出現(xiàn)解決了數(shù)組長度固定的問題。集合的長度是可變的,可以隨著元素的添加自動(dòng)擴(kuò)容。例如,我們可以使用 ArrayList
來存儲(chǔ)多個(gè)元素,而無需擔(dān)心長度的限制。
2.3 集合存儲(chǔ)數(shù)據(jù)類型的特點(diǎn)
2.3.1 數(shù)組存儲(chǔ)類型
數(shù)組既可以存儲(chǔ)基本數(shù)據(jù)類型,也可以存儲(chǔ)引用數(shù)據(jù)類型。例如:
int[] arr1 = new int[3]; // 存儲(chǔ)基本數(shù)據(jù)類型 class User { String name; int age; public User(String name, int age) { this.name = name; this.age = age; } } User u1 = new User("小紅", 13); User u2 = new User("小明", 13); User[] userArr = new User[2]; userArr[0] = u1; userArr[1] = u2; // 存儲(chǔ)引用數(shù)據(jù)類型
2.3.2 集合存儲(chǔ)類型
集合只能存儲(chǔ)引用數(shù)據(jù)類型。如果要存儲(chǔ)基本數(shù)據(jù)類型,需要將其轉(zhuǎn)換為對應(yīng)的包裝類。這是因?yàn)?Java 集合框架是基于泛型實(shí)現(xiàn)的,而泛型只能接受引用類型。例如,要存儲(chǔ)整數(shù),我們需要使用 Integer
包裝類:
import java.util.ArrayList; ArrayList<Integer> list = new ArrayList<>(); list.add(1); // 自動(dòng)裝箱,將 int 類型的 1 轉(zhuǎn)換為 Integer 類型
2.4 集合和數(shù)組的對比
對比項(xiàng) | 數(shù)組 | 集合 |
---|---|---|
長度 | 長度固定,創(chuàng)建后不能改變 | 長度可變,可根據(jù)元素?cái)?shù)量自動(dòng)調(diào)整 |
存儲(chǔ)類型 | 可以存儲(chǔ)基本數(shù)據(jù)類型和引用數(shù)據(jù)類型 | 只能存儲(chǔ)引用數(shù)據(jù)類型,存儲(chǔ)基本數(shù)據(jù)類型需使用包裝類 |
操作靈活性 | 操作相對簡單,主要通過索引訪問和修改元素 | 提供了豐富的操作方法,如添加、刪除、修改、查找等 |
三、集合:ArrayList
3.1 ArrayList 概述
ArrayList
是 Java 集合框架中最常用的類之一,它實(shí)現(xiàn)了 List
接口,底層基于數(shù)組實(shí)現(xiàn)。ArrayList
允許存儲(chǔ)重復(fù)元素,并且可以根據(jù)需要?jiǎng)討B(tài)調(diào)整大小。
3.2 創(chuàng)建 ArrayList 對象
import java.util.ArrayList; public class ArrayListExample { public static void main(String[] args) { // 1. 創(chuàng)建集合的對象 // 泛型:限定集合中存儲(chǔ)的數(shù)據(jù)類型 ArrayList<String> list = new ArrayList<String>(); // JDK 7 以后,泛型的類型可以省略,但是前后必須一致,就是右邊 <> 里面可以不寫 // 此時(shí)我們創(chuàng)建的是 ArrayList 的對象,而 ArrayList 是 Java 已經(jīng)寫好的一個(gè)類 // 這個(gè)類在底層做了一些處理,打印對象不是地址值,而是集合中的內(nèi)容 // 在展示的時(shí)候,它會(huì)拿 [] 把里面的內(nèi)容給框起來 System.out.println(list); } } // 運(yùn)行結(jié)果: []
在上述代碼中,我們創(chuàng)建了一個(gè) ArrayList
對象,并指定了泛型類型為 String
,表示該集合只能存儲(chǔ) String
類型的元素。
3.3 ArrayList 底層實(shí)現(xiàn)原理
ArrayList
底層使用一個(gè)動(dòng)態(tài)數(shù)組來存儲(chǔ)元素。當(dāng)我們創(chuàng)建一個(gè) ArrayList
對象時(shí),會(huì)默認(rèn)分配一個(gè)初始容量(通常為 10)。當(dāng)添加元素時(shí),如果數(shù)組的容量不足,ArrayList
會(huì)自動(dòng)進(jìn)行擴(kuò)容。擴(kuò)容的過程是創(chuàng)建一個(gè)新的數(shù)組,其容量通常是原數(shù)組的 1.5 倍,然后將原數(shù)組的元素復(fù)制到新數(shù)組中。
3.4 ArrayList 成員方法
方法名 | 說明 |
---|---|
boolean add (E e) | 添加元素,返回值表示是否添加成功 |
boolean remove (E e) | 刪除指定元素,返回值表示是否刪除成功 |
E set (int index , E e) | 修改指定索引下的元素,返回原來的元素 |
E get (int index) | 獲取指定索引的元素 |
E remove (int index) | 刪除指定索引下的元素,返回原來的元素 |
int size () | 集合的長度,也就是集合中元素的個(gè)數(shù) |
3.4.1 添加元素
import java.util.ArrayList; public class ArrayListAddExample { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); boolean b1 = list.add("aaa"); list.add("bbb"); list.add("ccc"); System.out.println(list); System.out.println(b1); } }
add(E e)
方法用于向集合中添加元素,返回值表示是否添加成功。在 ArrayList
中,該方法通常返回 true
,因?yàn)樗偸强梢猿晒μ砑釉亍?/p>
3.4.2 刪除元素
import java.util.ArrayList; public class ArrayListRemoveExample { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); list.remove("aaa"); System.out.println(list); } }
remove(E e)
方法用于刪除指定元素,返回值表示是否刪除成功。如果集合中存在該元素,則刪除并返回 true
;否則返回 false
。
3.4.3 修改元素
import java.util.ArrayList; public class ArrayListSetExample { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.set(0, "ddd"); System.out.println(list); } }
set(int index, E e)
方法用于修改指定索引下的元素,返回原來的元素。
3.4.4 獲取元素
import java.util.ArrayList; public class ArrayListGetExample { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); String s = list.get(0); System.out.println(s); } }
get(int index)
方法用于獲取指定索引的元素。
3.4.5 刪除指定索引的元素
import java.util.ArrayList; public class ArrayListRemoveIndexExample { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); String removed = list.remove(0); System.out.println(list); System.out.println(removed); } }
remove(int index)
方法用于刪除指定索引下的元素,返回原來的元素。
3.4.6 獲取集合長度
import java.util.ArrayList; public class ArrayListSizeExample { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); int size = list.size(); System.out.println(size); } }
size()
方法用于獲取集合的長度,即集合中元素的個(gè)數(shù)。
3.4.7 遍歷集合
import java.util.ArrayList; public class ArrayListTraversalExample { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); // 普通 for 循環(huán)遍歷 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } // 增強(qiáng) for 循環(huán)遍歷 for (String element : list) { System.out.println(element); } // 使用迭代器遍歷 java.util.Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
在上述代碼中,我們展示了三種遍歷 ArrayList
的方式:普通 for
循環(huán)、增強(qiáng) for
循環(huán)和迭代器。不同的遍歷方式適用于不同的場景,例如,普通 for
循環(huán)可以在遍歷過程中修改元素,而增強(qiáng) for
循環(huán)和迭代器則更簡潔。
四、ArrayList 的性能分析
4.1 時(shí)間復(fù)雜度
- 添加元素:在列表末尾添加元素的時(shí)間復(fù)雜度為 (O(1)),但在中間或開頭添加元素需要移動(dòng)后續(xù)元素,時(shí)間復(fù)雜度為 (O(n))。
- 刪除元素:刪除末尾元素的時(shí)間復(fù)雜度為 (O(1)),刪除中間或開頭元素需要移動(dòng)后續(xù)元素,時(shí)間復(fù)雜度為 (O(n))。
- 查找元素:通過索引查找元素的時(shí)間復(fù)雜度為 (O(1)),通過元素值查找元素需要遍歷列表,時(shí)間復(fù)雜度為 (O(n))。
- 修改元素:通過索引修改元素的時(shí)間復(fù)雜度為 (O(1))。
4.2 空間復(fù)雜度
ArrayList
的空間復(fù)雜度主要取決于存儲(chǔ)的元素?cái)?shù)量和數(shù)組的容量。在擴(kuò)容時(shí),會(huì)額外分配一定的空間,因此空間復(fù)雜度為 (O(n))。
五、總結(jié)
復(fù)雜度為 (O(1)),刪除中間或開頭元素需要移動(dòng)后續(xù)元素,時(shí)間復(fù)雜度為 (O(n))。
- 查找元素:通過索引查找元素的時(shí)間復(fù)雜度為 (O(1)),通過元素值查找元素需要遍歷列表,時(shí)間復(fù)雜度為 (O(n))。
- 修改元素:通過索引修改元素的時(shí)間復(fù)雜度為 (O(1))。
5.2 空間復(fù)雜度
ArrayList
的空間復(fù)雜度主要取決于存儲(chǔ)的元素?cái)?shù)量和數(shù)組的容量。在擴(kuò)容時(shí),會(huì)額外分配一定的空間,因此空間復(fù)雜度為 (O(n))。
ArrayList
是 Java 集合框架中一個(gè)非常實(shí)用的類,它提供了動(dòng)態(tài)數(shù)組的功能,方便我們存儲(chǔ)和操作多個(gè)元素。通過了解 ArrayList
的底層實(shí)現(xiàn)原理、成員方法和性能特點(diǎn),我們可以在實(shí)際開發(fā)中更加合理地使用它,提高代碼的性能和可維護(hù)性。同時(shí),我們也應(yīng)該注意 ArrayList
在某些場景下的局限性,例如在頻繁插入和刪除元素的場景下,性能可能不如其他集合類,如 LinkedList
。
到此這篇關(guān)于Java ArrayList集合之解鎖數(shù)據(jù)存儲(chǔ)新姿勢的文章就介紹到這了,更多相關(guān)Java ArrayList集合數(shù)據(jù)存儲(chǔ)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
前置++和后置++ 運(yùn)算的詳解及實(shí)例代碼
這篇文章主要介紹了前置++和后置++ 的相關(guān)資料,并附示例代碼,幫助大家學(xué)習(xí)參考,需要的朋友可以參考下2016-09-09springboot @validated List校驗(yàn)失效問題
這篇文章主要介紹了springboot @validated List校驗(yàn)失效問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07Java的lambda表達(dá)式實(shí)現(xiàn)解析
這篇文章主要為大家詳細(xì)介紹了Java的lamda表達(dá)式實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Java ArrayList 數(shù)組之間相互轉(zhuǎn)換
本文通過代碼示例給大家講解arraylist轉(zhuǎn)化為數(shù)組,然后數(shù)組轉(zhuǎn)化為arraylist的相關(guān)資料,感興趣的朋友一起看看吧2015-11-11CMD運(yùn)行Intellij Idea編譯后的class文件操作
這篇文章主要介紹了CMD運(yùn)行Intellij Idea編譯后的class文件操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02