詳解Java?List中五種常見實(shí)現(xiàn)類的使用
一、 List概述
Java中的List是一個(gè)接口,它繼承自Collection接口,代表了一個(gè)有序的集合,其中的元素可以重復(fù)。List提供了一系列方法用于對(duì)集合中的元素進(jìn)行操作,例如添加、刪除、獲取元素等。Java中常見的List實(shí)現(xiàn)類有ArrayList、LinkedList、Vector、Stack和CopyOnWriteArrayList。
在實(shí)際開發(fā)中,List接口是一種頻繁使用的數(shù)據(jù)結(jié)構(gòu),它提供了豐富的方法來操作有序的元素集合。由于其靈活性和常用性,List在許多場(chǎng)景下被廣泛應(yīng)用,是開發(fā)人員經(jīng)常選擇的數(shù)據(jù)結(jié)構(gòu)之一。
1.1 List 接口的常見實(shí)現(xiàn)類
Java中提供了非常多的使用的List實(shí)現(xiàn)類,本文將重點(diǎn)介紹一下這些類以及他們的應(yīng)用場(chǎng)景。首先羅列一下本文要介紹的實(shí)現(xiàn)類都有哪些。

1.2 List接口都定義了那些方法

List接口里面定義的方法還是挺多的,大體可以分為六類,下面我將這些方法分類說明一下:

1.添加元素:
- boolean add(E element):向列表的末尾添加一個(gè)元素。
- void add(int index, E element):在指定的索引位置添加一個(gè)元素。
2.獲取元素:
- E get(int index):獲取指定索引位置的元素。
- int indexOf(Object obj):返回指定元素在列表中首次出現(xiàn)的索引。
- int lastIndexOf(Object obj):返回指定元素在列表中最后出現(xiàn)的索引。
3.刪除元素:
- boolean remove(Object obj):從列表中刪除指定元素的第一個(gè)匹配項(xiàng)。
- E remove(int index):刪除指定索引位置的元素。
4.修改元素:
E set(int index, E element):替換指定索引位置的元素。
5.列表大?。?/p>
- int size():返回列表中的元素?cái)?shù)量。
- boolean isEmpty():檢查列表是否為空。
6.遍歷元素:
- 使用迭代器(Iterator)遍歷列表中的元素。
- 使用增強(qiáng)的for循環(huán)(for-each)遍歷列表中的元素。
二、ArrayList

ArrayList是一個(gè)動(dòng)態(tài)數(shù)組實(shí)現(xiàn)的類,它是Java集合框架中List接口的一個(gè)常用實(shí)現(xiàn)類。與傳統(tǒng)的數(shù)組相比,ArrayList具有更靈活的長(zhǎng)度和操作方式。
通過使用ArrayList,可以方便地管理和操作元素集合,它是Java開發(fā)中常用的數(shù)據(jù)結(jié)構(gòu)之一。
2.1 ArrayList的特點(diǎn)
- 動(dòng)態(tài)數(shù)組:ArrayList在內(nèi)部使用數(shù)組來存儲(chǔ)元素,并且具有動(dòng)態(tài)擴(kuò)容的能力。當(dāng)元素?cái)?shù)量超過當(dāng)前數(shù)組容量時(shí),ArrayList會(huì)自動(dòng)增加其容量以容納更多的元素。
- 有序集合:ArrayList是一個(gè)有序集合,可以按照元素的插入順序迭代訪問元素。
- 允許重復(fù)元素:ArrayList允許存儲(chǔ)重復(fù)的元素,即可以在列表中存儲(chǔ)相同的元素多次。
- 隨機(jī)訪問:由于ArrayList使用基于索引的數(shù)組實(shí)現(xiàn),因此可以通過索引進(jìn)行快速的隨機(jī)訪問和修改元素。可以使用get(index)方法根據(jù)索引獲取元素,使用set(index, element)方法根據(jù)索引修改元素。
- 動(dòng)態(tài)修改:ArrayList提供了一系列方法來動(dòng)態(tài)修改列表,包括添加元素、刪除元素、插入元素等。常用的方法包括add(element)用于在列表末尾添加元素,remove(element)用于刪除指定元素,add(index, element)用于在指定位置插入元素等。
- 支持迭代器:ArrayList實(shí)現(xiàn)了Iterable接口,因此可以使用迭代器來遍歷列表中的元素??梢酝ㄟ^iterator()方法獲取迭代器,并使用hasNext()和next()方法依次訪問元素。
- 非線程安全:ArrayList不是線程安全的,如果在多個(gè)線程同時(shí)修改ArrayList時(shí),需要進(jìn)行外部同步或使用線程安全的替代類,如CopyOnWriteArrayList。
2.2 ArrayList使用案例
demo:
import java.util.ArrayList;
import java.util.List;
public class ArrayListDemo {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("蘋果");
fruits.add("香蕉");
fruits.add("榴蓮");
fruits.add("菠蘿");
// 獲取ArrayList的大小
int size = fruits.size();
System.out.println("ArrayList的大?。? + size);
// 訪問指定位置的元素
String element = fruits.get(2);
System.out.println("索引2上的元素:" + element);
// 修改指定位置的元素
fruits.set(1, "菠蘿蜜");
System.out.println("修改后的ArrayList:" + fruits);
// 刪除指定位置的元素
String removedElement = fruits.remove(3);
System.out.println("被刪除的元素:" + removedElement);
System.out.println("刪除后的ArrayList:" + fruits);
// 檢查ArrayList是否包含某個(gè)元素
boolean contains = fruits.contains(30);
System.out.println("ArrayList是否包含30:" + contains);
// 清空ArrayList
fruits.clear();
System.out.println("清空后的ArrayList:" + fruits);
}
}
輸出結(jié)果:
ArrayList的大?。?
索引2上的元素:榴蓮
修改后的ArrayList:[蘋果, 菠蘿蜜, 榴蓮, 菠蘿]
被刪除的元素:菠蘿
刪除后的ArrayList:[蘋果, 菠蘿蜜, 榴蓮]
ArrayList是否包含30:false
清空后的ArrayList:[]
三、LinkedList

LinkedList是Java集合框架中的一個(gè)實(shí)現(xiàn)類,它實(shí)現(xiàn)了List接口和Deque接口,基于雙向鏈表的數(shù)據(jù)結(jié)構(gòu)。相比于ArrayList,LinkedList在某些場(chǎng)景下具有一些特殊的優(yōu)勢(shì)和適用性。
LinkedList適用于需要頻繁進(jìn)行插入和刪除操作的場(chǎng)景,特別是在實(shí)現(xiàn)隊(duì)列和棧時(shí)。
3.1 LinkedList的特點(diǎn)
- 雙向鏈表:LinkedList內(nèi)部使用雙向鏈表來存儲(chǔ)元素。每個(gè)節(jié)點(diǎn)都包含對(duì)前一個(gè)節(jié)點(diǎn)和后一個(gè)節(jié)點(diǎn)的引用,因此在插入和刪除元素時(shí),LinkedList比ArrayList更高效。由于不需要像ArrayList那樣進(jìn)行數(shù)組的擴(kuò)容和元素的移動(dòng),LinkedList對(duì)于頻繁的插入和刪除操作更快。
- 高效的插入和刪除操作:由于LinkedList的雙向鏈表結(jié)構(gòu),插入和刪除元素的平均時(shí)間復(fù)雜度為O(1),而在ArrayList中,這些操作的時(shí)間復(fù)雜度為O(n),其中n是元素的數(shù)量。因此,在需要頻繁進(jìn)行插入和刪除操作的場(chǎng)景下,LinkedList通常比ArrayList更適合。
- 低效的隨機(jī)訪問:由于LinkedList是基于鏈表實(shí)現(xiàn)的,訪問元素需要從頭節(jié)點(diǎn)或尾節(jié)點(diǎn)開始遍歷鏈表,因此隨機(jī)訪問元素的效率較低。在需要頻繁進(jìn)行隨機(jī)訪問的場(chǎng)景下,ArrayList通常更適合。
- 適合實(shí)現(xiàn)隊(duì)列和棧:LinkedList實(shí)現(xiàn)了Queue接口和Deque接口,因此可以用作隊(duì)列(先進(jìn)先出)和棧(后進(jìn)先出)的數(shù)據(jù)結(jié)構(gòu)。它提供了相關(guān)的方法,如add()和remove()用于隊(duì)列操作,以及push()和pop()用于棧操作。
- 內(nèi)存消耗較大:相比于ArrayList,LinkedList在存儲(chǔ)相同數(shù)量元素時(shí)需要更多的內(nèi)存,因?yàn)槊總€(gè)節(jié)點(diǎn)都需要額外的引用來指向前一個(gè)節(jié)點(diǎn)和后一個(gè)節(jié)點(diǎn)。
3.2 LinkedList使用案例
demo:
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)LinkedList,用于存儲(chǔ)字符串
LinkedList<String> names = new LinkedList<>();
// 添加元素到LinkedList
names.add("張三");
names.add("李四");
names.add("王五");
names.add("趙六");
// 獲取LinkedList的大小
int size = names.size();
System.out.println("LinkedList的大?。? + size);
// 訪問指定位置的元素
String element = names.get(2);
System.out.println("索引2上的元素:" + element);
// 修改指定位置的元素
names.set(1, "林七");
System.out.println("修改后的LinkedList:" + names);
// 刪除指定位置的元素
String removedElement = names.remove(3);
System.out.println("被刪除的元素:" + removedElement);
System.out.println("刪除后的LinkedList:" + names);
// 在特定位置插入元素
names.add(0, "馬八");
System.out.println("插入后的LinkedList:" + names);
// 檢查L(zhǎng)inkedList是否包含某個(gè)元素
boolean contains = names.contains("李四");
System.out.println("LinkedList是否包含李四:" + contains);
// 清空LinkedList
names.clear();
System.out.println("清空后的LinkedList:" + names);
}
}
輸出結(jié)果:
LinkedList的大?。?
索引2上的元素:王五
修改后的LinkedList:[張三, 林七, 王五, 趙六]
被刪除的元素:趙六
刪除后的LinkedList:[張三, 林七, 王五]
插入后的LinkedList:[馬八, 張三, 林七, 王五]
LinkedList是否包含李四:false
清空后的LinkedList:[]
四、Vector

Vector是Java集合框架中的一個(gè)類,它實(shí)現(xiàn)了List接口,是一個(gè)動(dòng)態(tài)數(shù)組(類似于ArrayList)的線程安全版本。與ArrayList相比,Vector具有額外的同步機(jī)制,可以在多線程環(huán)境中安全地使用。
雖然Vector具有線程安全的特性,但由于同步機(jī)制的開銷,它在性能上可能不如ArrayList。因此,如果在單線程環(huán)境下工作,建議使用ArrayList;僅在多線程環(huán)境下需要線程安全操作時(shí),才考慮使用Vector。
需要注意的是,在Java 5及以后的版本中,推薦使用更加高效的并發(fā)集合類,如CopyOnWriteArrayList或ConcurrentLinkedDeque,來替代Vector,因?yàn)樗鼈兲峁└玫男阅芎蛿U(kuò)展性。
4.1 Vector 的特點(diǎn)
- 動(dòng)態(tài)數(shù)組:Vector內(nèi)部使用數(shù)組來存儲(chǔ)元素,并且具有動(dòng)態(tài)擴(kuò)容的能力。當(dāng)元素?cái)?shù)量超過當(dāng)前數(shù)組容量時(shí),Vector會(huì)自動(dòng)增加其容量以容納更多的元素。
- 線程安全:Vector的操作是線程安全的,即多個(gè)線程可以同時(shí)對(duì)Vector進(jìn)行操作而不會(huì)導(dǎo)致數(shù)據(jù)不一致或其他線程安全問題。Vector通過使用同步機(jī)制來實(shí)現(xiàn)線程安全,確保在多線程環(huán)境中的并發(fā)訪問操作的正確性。
- 有序集合:Vector是一個(gè)有序集合,可以按照元素的插入順序迭代訪問元素。
- 允許重復(fù)元素:Vector允許存儲(chǔ)重復(fù)的元素,即可以在列表中存儲(chǔ)相同的元素多次。
- 隨機(jī)訪問:由于Vector使用基于索引的數(shù)組實(shí)現(xiàn),因此可以通過索引進(jìn)行快速的隨機(jī)訪問和修改元素??梢允褂胓et(index)方法根據(jù)索引獲取元素,使用set(index, element)方法根據(jù)索引修改元素。
- 動(dòng)態(tài)修改:Vector提供了一系列方法來動(dòng)態(tài)修改列表,包括添加元素、刪除元素、插入元素等。常用的方法包括add(element)用于在列表末尾添加元素,remove(element)用于刪除指定元素,add(index, element)用于在指定位置插入元素等。
- 迭代器支持:Vector實(shí)現(xiàn)了Iterable接口,因此可以使用迭代器來遍歷列表中的元素??梢酝ㄟ^iterator()方法獲取迭代器,并使用hasNext()和next()方法依次訪問元素。
4.2 Vector 使用案例
demo:
import java.util.Vector;
public class VectorExample {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)Vector,用于存儲(chǔ)整數(shù)
Vector<Integer> numbers = new Vector<>();
// 添加元素到Vector
numbers.add(11);
numbers.add(22);
numbers.add(33);
numbers.add(44);
// 獲取Vector的大小
int size = numbers.size();
System.out.println("Vector的大小:" + size);
// 訪問指定位置的元素
int element = numbers.get(2);
System.out.println("索引2上的元素:" + element);
// 修改指定位置的元素
numbers.set(1, 25);
System.out.println("修改后的Vector:" + numbers);
// 刪除指定位置的元素
int removedElement = numbers.remove(3);
System.out.println("被刪除的元素:" + removedElement);
System.out.println("刪除后的Vector:" + numbers);
// 在特定位置插入元素
numbers.add(0, 5);
System.out.println("插入后的Vector:" + numbers);
// 檢查Vector是否包含某個(gè)元素
boolean contains = numbers.contains(30);
System.out.println("Vector是否包含30:" + contains);
// 清空Vector
numbers.clear();
System.out.println("清空后的Vector:" + numbers);
}
}
輸出結(jié)果:
Vector的大?。?
索引2上的元素:33
修改后的Vector:[11, 25, 33, 44]
被刪除的元素:44
刪除后的Vector:[11, 25, 33]
插入后的Vector:[5, 11, 25, 33]
Vector是否包含30:false
清空后的Vector:[]
五、Stack

Stack(棧)是Java集合框架中的一個(gè)類,它實(shí)現(xiàn)了"后進(jìn)先出"(Last-In-First-Out,LIFO)的數(shù)據(jù)結(jié)構(gòu)。Stack繼承自Vector類,因此具有Vector的所有特性,同時(shí)提供了一些額外的棧操作方法。
Stack的主要用途是在需要后進(jìn)先出操作的場(chǎng)景中,例如在逆序輸出、括號(hào)匹配、深度優(yōu)先搜索等算法中常用到。需要注意的是,由于Stack繼承自Vector,它具有線程安全的特性,但在性能上可能不如其他非同步的棧實(shí)現(xiàn),如ArrayDeque。因此,在不需要線程安全操作的情況下,可以考慮使用ArrayDeque代替Stack。
5.1 Stack 的特點(diǎn)
- 后進(jìn)先出(LIFO):Stack中的元素按照后進(jìn)先出的順序進(jìn)行操作。最后添加的元素將首先被訪問或刪除,而最先添加的元素將最后被訪問或刪除。
- 繼承自Vector:Stack繼承了Vector類的所有功能,包括動(dòng)態(tài)數(shù)組實(shí)現(xiàn)、隨機(jī)訪問、動(dòng)態(tài)修改等。由于Stack是Vector的子類,因此可以使用Vector的所有方法來操作棧。
- 壓棧和出棧:Stack提供了push(element)方法用于將元素壓入棧頂,以及pop()方法用于從棧頂彈出并返回棧頂元素。通過這兩個(gè)方法,可以實(shí)現(xiàn)棧的基本操作。
- 查看棧頂元素:Stack提供了peek()方法,用于返回但不刪除棧頂元素。這個(gè)方法可以用于查看棧頂元素而不改變棧的狀態(tài)。
- 判空和棧大小:Stack提供了isEmpty()方法來檢查棧是否為空,以及size()方法來獲取棧中元素的數(shù)量。
- 搜索元素:Stack提供了search(element)方法,用于在棧中搜索指定元素,并返回相對(duì)于棧頂?shù)木嚯x(如果元素存在于棧中)。如果元素不存在于棧中,則返回-1。
5.2 Stack 使用案例
demo:
import java.util.Stack;
public class StackDemo {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)Stack,用于存儲(chǔ)整數(shù)
Stack<Integer> stack = new Stack<>();
// 壓入元素到棧頂
stack.push(66);
stack.push(88);
stack.push(99);
// 查看棧頂元素
int topElement = stack.peek();
System.out.println("棧頂元素:" + topElement);
// 彈出棧頂元素
int poppedElement = stack.pop();
System.out.println("彈出的元素:" + poppedElement);
// 查看棧的大小
int size = stack.size();
System.out.println("棧的大?。? + size);
// 判斷棧是否為空
boolean isEmpty = stack.isEmpty();
System.out.println("棧是否為空:" + isEmpty);
}
}
輸出結(jié)果:
棧頂元素:99
彈出的元素:99
棧的大?。?
棧是否為空:false
六、CopyOnWriteArrayList

CopyOnWriteArrayList是Java并發(fā)集合框架中的一種線程安全的列表實(shí)現(xiàn)。
由于CopyOnWriteArrayList的寫操作會(huì)創(chuàng)建新的副本,因此在多個(gè)線程同時(shí)進(jìn)行寫操作時(shí),不會(huì)發(fā)生數(shù)據(jù)不一致的情況。最終輸出的列表中包含了所有寫線程添加的元素。
注意,由于CopyOnWriteArrayList的特性,讀取操作不會(huì)受到寫操作的影響,因此可以安全地在寫操作進(jìn)行時(shí)進(jìn)行讀取操作。
6.1 CopyOnWriteArrayList 的特點(diǎn)
- 線程安全:CopyOnWriteArrayList通過在修改操作時(shí)創(chuàng)建一個(gè)新的副本來實(shí)現(xiàn)線程安全性。這意味著多個(gè)線程可以同時(shí)進(jìn)行讀取操作,而不會(huì)阻塞彼此,且讀取操作不會(huì)受到修改操作的影響。
- 寫時(shí)復(fù)制:在修改操作(如添加、修改、刪除元素)時(shí),CopyOnWriteArrayList會(huì)創(chuàng)建一個(gè)數(shù)組的新副本,以保持原有數(shù)組的不可變性。這意味著修改操作不會(huì)直接修改原始數(shù)組,而是在新副本上進(jìn)行操作,從而保證了讀取操作的線程安全性。
- 高效的讀取操作:由于讀取操作不需要進(jìn)行同步或加鎖,所以讀取操作的性能很高。適用于讀多寫少的場(chǎng)景。
- 適用于靜態(tài)數(shù)據(jù)集:CopyOnWriteArrayList適用于靜態(tài)數(shù)據(jù)集,即在創(chuàng)建后很少有修改操作。如果需要頻繁進(jìn)行修改操作,可能會(huì)產(chǎn)生較高的內(nèi)存開銷,因?yàn)槊看涡薷亩紩?huì)創(chuàng)建新的副本。
6.2 CopyOnWriteArrayList 使用案例
demo:
import java.util.concurrent.CopyOnWriteArrayList;
public class CopyOnWriteArrayListDemo {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)CopyOnWriteArrayList,用于存儲(chǔ)整數(shù)
CopyOnWriteArrayList<Integer> numbers = new CopyOnWriteArrayList<>();
// 創(chuàng)建并啟動(dòng)多個(gè)線程進(jìn)行寫操作
for (int i = 0; i < 5; i++) {
int finalI = i;
Thread thread = new Thread(() -> {
numbers.add(finalI);
System.out.println("線程" + Thread.currentThread().getName() + ":添加元素 " + finalI);
});
thread.start();
}
// 等待所有寫線程執(zhí)行完畢
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 輸出列表中的元素
System.out.println("列表中的元素:" + numbers);
}
}
輸出結(jié)果:
線程Thread-0:添加元素 0
線程Thread-4:添加元素 4
線程Thread-3:添加元素 3
線程Thread-1:添加元素 1
線程Thread-2:添加元素 2
列表中的元素:[0, 1, 3, 4, 2]
七、總結(jié)
ArrayList、LinkedList、Vector、Stack和CopyOnWriteArrayList都是Java集合框架中的List的實(shí)現(xiàn)類,用于存儲(chǔ)有序的元素集合,但它們?cè)诘讓訑?shù)據(jù)結(jié)構(gòu)、線程安全性以及性能特點(diǎn)上存在一些差異。
在實(shí)際開發(fā)中我們要根據(jù)業(yè)務(wù)的需求來合理的選擇不同的數(shù)據(jù)結(jié)構(gòu)。
以上就是詳解Java List中五種常見實(shí)現(xiàn)類的使用的詳細(xì)內(nèi)容,更多關(guān)于Java List的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Spring boot+CXF開發(fā)WebService Demo
這篇文章主要介紹了詳解Spring boot+CXF開發(fā)WebService Demo,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05
SpringBoot+ECharts是如何實(shí)現(xiàn)數(shù)據(jù)可視化的
今天帶大家學(xué)習(xí)的是關(guān)于Java的相關(guān)知識(shí),文章圍繞著SpringBoot+ECharts怎么實(shí)現(xiàn)數(shù)據(jù)可視化展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
cmd中javac命令無法運(yùn)行(java指令能運(yùn)行)解決步驟
這篇文章主要介紹了在安裝JDK后,執(zhí)行javac命令沒有返回值的問題,可能是由于命令提示符窗口緩存問題、系統(tǒng)路徑優(yōu)先級(jí)問題、文件權(quán)限問題或命令行輸入問題,文中通過代碼將解決的步驟介紹的非常詳細(xì),需要的朋友可以參考下2025-02-02
JAVA驗(yàn)證身份證號(hào)碼有效性的實(shí)例代碼
很多項(xiàng)目業(yè)務(wù)都會(huì)設(shè)計(jì)到人員信息,那么身份證號(hào)就是必不可少的校驗(yàn)項(xiàng),下面這篇文章主要給大家介紹了關(guān)于JAVA驗(yàn)證身份證號(hào)碼有效性的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
關(guān)于json序列化(javaBean轉(zhuǎn)Json的細(xì)節(jié)處理)
這篇文章主要介紹了關(guān)于json序列化(javaBean轉(zhuǎn)Json的細(xì)節(jié)處理),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2022-03-03

