Java中ArrayList與LinkedList的使用及區(qū)別詳解
一、List
1.什么是List?
在集合框架中,List就是一個接口,繼承于Collection接口。
在數(shù)據(jù)結構的角度,List就是一個線性表,即n個具有相同類型元素的有限序列,在該序列上可以執(zhí)行增刪查改以及變量等操作。
什么是線性表?
線性表是由n個具有相同類型元素組成的有限序列。線性表是一種常見的數(shù)據(jù)結構。在邏輯上,線性表是一種線性結構,就是連續(xù)的一條直線,在物理結構上,不一定是連續(xù)的,在物理存儲是,通常是以數(shù)組和鏈式的結構形式存儲。常見的線性比表有順序表、鏈表、棧、隊列.......
2.List中的常用方法
| 增 | |
| boolean add(E e) | 插入元素e在末尾 |
| void add(int index,E element) | 插入元素e在index位置 |
| boolean addAll(Collection?extends?E>c) | 尾插c中的元素 |
| 刪 | |
| E remove(int index) | 刪除index位置的元素 |
| boolean remove(Object o) | 刪除第一次出現(xiàn)的o元素 |
| void clear() | 清空 |
| 查 | |
| E get(int index) | 獲取index下標位置元素 |
| int indexOf(Object o) | 獲取第一個o元素所在的下標 |
| int lastindexOf(Object o) | 獲取最后一個o元素所在的下標 |
| boolean contains(Object o) | 查看是否包含o元素 |
| 改 | |
| E set(int index,E Element) | 將index下標的元素改為e |
| 截取 | |
| List<E>subList(int formIndex,int toIndex) | 截取部分list |
List是一個接口,所以不能直接實例化。如果想要使用list接口,必須實例化list的實現(xiàn)類。
在集合框架中,ArrayList和LinkedList都實現(xiàn)了這個接口。
二、ArrayList
1.什么是ArrayList?
ArrayList是一個普通的類,是順序表的一種,實現(xiàn)了list接口,是一種可動態(tài)調整大小的數(shù)組,能夠儲存不同類型的對象。
什么是順序表?
順序表是用一段物理地址連續(xù)的存儲單元依次存儲數(shù)據(jù)元素的線性結構,一般情況下采用數(shù)組存儲。在數(shù)組上完成數(shù)據(jù)的增刪查改。
2.ArrayList的實例化
//接口的實例化:
List<Integer> list1=new ArrayList<>();
//ArrayList的實例化:
ArrayList<Integer> list=new ArrayList<>();
兩者區(qū)別:
- 接口的實例化:只能使用接口中定義類的方法;
- ArrayList實例化:可以使用ArrayList中獨有的方法,更具有靈活性
3.ArrayList的使用
ArrayList常見方法:
| 增: | |
| void add(int data) | 在數(shù)組最后添加元素 |
| void add(int pos,int data) | 在數(shù)組某下標插入元素 |
| 刪: | |
| void remove(int toRemove) | 刪除第一次出現(xiàn)的元素 |
| void clear(); | 清空所有元素 |
| 查: | |
boolean contains(int toFind) | 查看是否包含該元素 |
| int get(int pos) | 獲取該下標元素 |
| int indexOf(int toFind ) | 獲取該元素下標 |
| 改: | |
| void set(int pos,int value) | 將下標元素進行更改 |
ArrayList方法的使用:
public static void main(String[] args) {
List<Integer> list1=new ArrayList<>();
//增:
//add:尾插
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
System.out.println(list1);//[1, 2, 3, 4, 5]
//add:任意位置插入
list1.add(3,100);
System.out.println(list1);//[1, 2, 3, 100, 4, 5]
//查:
//contains:是否包含該元素
System.out.println(list1.contains(11));//false
//get:獲取下標元素
int ret=list1.get(3);
System.out.println(ret);//100
//indexOf:獲取元素下標
int ret2=list1.indexOf(4);
System.out.println(ret2);//4
//改
//set:將某下標的元素進行更改
list1.set(1,13);
System.out.println(list1);//[1, 13, 3, 100, 4, 5]
//刪:
// remove:刪除第一次出現(xiàn)的元素
list1.remove(2);
list1.remove(3);
//list1.remove(6);//超出范圍,報錯
System.out.println(list1);//[1, 13, 100, 5]
//清空
list1.clear();
System.out.println(list1);//無
//大小的獲取:
System.out.println(list1.size());
}
4.ArrayList的遍歷
ArrayList的遍歷可以使用三種方法:for循環(huán)、foreach、使用迭代器
示例:
public static void main(String[] args) {
List<Integer> list1=new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
}for循環(huán):
//for循環(huán)語句:
//list1.size():list1長度
for (int i = 0; i < list1.size(); i++) {
//get(i):獲取i下標的元素
System.out.print(list1.get(i)+" ");//1 2 3 4 5
}foreach語句:
//foreach:
//每次循環(huán)時,取出list中的一個元素,將該元素賦值給變量num中
for (Integer num:list1) {
System.out.print(num+" ");//1 2 3 4 5
}迭代器:Iterator和ListIterator
//迭代器:
//從前往后打印
// Iterator
System.out.println("=====Iterator=====");
Iterator<Integer> a=list1.iterator();
//a.hasNext():用于判斷集合a中是否還有下一個元素,如果有返回true,沒有返回false
while(a.hasNext()){
//a.next:返回迭代器當前所指向的元素,然后指向下一個元素未被遍歷的元素并打印
System.out.print(a.next()+" ");
}
System.out.println();
//listIterator
System.out.println("=====listIterator=====");
ListIterator<Integer> b=list1.listIterator();
while(b.hasNext()){
System.out.print(b.next()+" ");//1 2 3 4 5
}
System.out.println();
System.out.println("=====listIterator=====");
//從后往前打印
ListIterator<Integer> c=list1.listIterator(list1.size());
//b.hasPrevious():用于判斷集合a中是否有上一個元素,如果有返回true,沒有返回false
while(b.hasPrevious()){
//b.previous:返回迭代器當前所指向的元素,然后指向上一個元素未被遍歷的元素并打印
System.out.print(b.previous()+" ");//5 4 3 2 1
}- ArrayList適合使用for循環(huán)語句遍歷;
Iterator和Listiterator的區(qū)別:
- Iterator是Java中的一個接口,通過hasNext()和next()方法實現(xiàn)順序遍歷;
- Listiterator是Iterator的子接口,除了擁有Iterator的方法外,還有其他功能,所以其還有雙向遍歷的功能,通過hasPrevious()和previous()來實現(xiàn)反向遍歷。
5.ArrayList特點
- 動態(tài)數(shù)組結構:基于數(shù)組實現(xiàn)??梢韵衿胀〝?shù)組一樣快速訪問元素;
- 動態(tài)調整大小:與普通數(shù)組不同,當添加的元素個數(shù)大于ArrayList容量,ArrayList會自動擴容1.5倍;
- 元素儲存有序:元素按照先后添加的順序在排序中,在插入或者刪除元素的時候,會相應改變元素位置;
- 允許元素重復:可以添加多個重復相同的元素;
- 通用性好:可以儲存各類對象。
6.ArrayList優(yōu)缺點
1.ArrayList的優(yōu)點:
- 快速訪問元素:基于數(shù)組實現(xiàn),可以快速訪問元素,時間復雜度為O(1);
- 內存利用相對高效:內存布局相對規(guī)整,主要是數(shù)組占用空間和少量額外空間用于記錄數(shù)組大小等信息。在不用頻繁的插入和刪除中間元素的情況下,內存利用高效;
- 支持隨機訪問:可以隨機訪問任意位置的元素,在很多算法和操作中非常有用,如二分查找。
2.ArrayList的缺點:
- 擴容開銷:當元素數(shù)量大于數(shù)組容量的時候,會進行擴容。在擴容時會創(chuàng)建一個新的容量更大的數(shù)組并復制舊元素,這會消耗較多的時間和資源;
- 插入和刪除的效率較低(中間元素):在頻繁的插入和刪除中間元素的時候,需要不斷地移動元素,時間復雜度為O(n)。
由于ArrayList不適合進行頻繁的插入和刪除元素,所以在Java集合中引入了LinkedList,即鏈表結構。
三、LinkedList
1.什么是LinkedList?
LinkedList的底層是雙向鏈表結構,是鏈表的一種。
什么是鏈表?
鏈表是一種常見的數(shù)據(jù)結構,它由一系列節(jié)點組成,每個節(jié)點包含數(shù)據(jù)域和指針域。鏈表邏輯順序是連續(xù)的,在物理存儲結構是非連續(xù)的。
鏈表的分類:
有頭鏈表或者無頭鏈表:
- 有頭鏈表:有一個的頭節(jié)點,其指針指向第一個數(shù)據(jù)節(jié)點;
- 無頭鏈表:沒有專門的頭節(jié)點,第一個節(jié)點直接存儲數(shù)據(jù);
以下分類都有分為是否是有頭鏈表還是無頭鏈表:
- 單鏈表:每個節(jié)點包含數(shù)據(jù)和下一個接節(jié)點的指針,最后一個節(jié)點的指針指向空
- 雙鏈表:每個節(jié)點都有包含數(shù)據(jù),以及指向前一個節(jié)點的指針和指向后一個節(jié)點的指針
- 循環(huán)鏈表:循環(huán)鏈表分為單循環(huán)鏈表和雙循環(huán)鏈表,其就是最后一個節(jié)點的下一個節(jié)點的指針指向其頭結點。
2.LinkedList的實例化
LinkedList<Integer> list1=new LinkedList<>();
3.LinkedList的使用
其常用方法與ArrayList相差不大
public static void main(String[] args) {
LinkedList<Integer> list1=new LinkedList<>();
//增:
//add:尾插
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
System.out.println(list1);//[1, 2, 3, 4, 5]
//add:任意位置插入
list1.add(3,100);
System.out.println(list1);//[1, 2, 3, 100, 4, 5]
//查:
//contains:是否包含該元素
System.out.println(list1.contains(11));//false
//get:獲取下標元素
int ret=list1.get(3);
System.out.println(ret);//100
//indexOf:獲取元素下標
int ret2=list1.indexOf(4);
System.out.println(ret2);//4
//改
//set:將某下標的元素進行更改
list1.set(1,13);
System.out.println(list1);//[1, 13, 3, 100, 4, 5]
//刪:
// remove:刪除第一次出現(xiàn)的元素
list1.remove(2);
list1.remove(3);
//list1.remove(6);//超出范圍,報錯
System.out.println(list1);//[1, 13, 100, 5]
//清空
list1.clear();
System.out.println(list1);//無
//大小的獲?。?
System.out.println(list1.size());//0
}4.LinkedList的遍歷
遍歷的三種方式:for循環(huán),foreach、迭代器
public static void main(String[] args) {
LinkedList<Integer> list1=new LinkedList<>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
//for循環(huán)語句:
for (int i = 0; i < list1.size(); i++) {
int ret=list1.get(i);
System.out.print(ret+" ");//1 2 3 4 5
}
System.out.println();
//foreach
for (Integer x:list1) {
System.out.print(x+" ");//1 2 3 4 5
}
System.out.println();
//迭代器:
Iterator<Integer> a=list1.iterator();
while (a.hasNext()){
System.out.print(a.next()+" ");//1 2 3 4 5
}
System.out.println();
ListIterator b=list1.listIterator();
while (b.hasNext()){
System.out.print(b.next()+" ");//1 2 3 4 5
}
System.out.println();
ListIterator c=list1.listIterator(list1.size());
while(c.hasPrevious()){
System.out.print(c.previous()+" ");//5 4 3 2 1
}
}- LinkedList適合使用迭代器遍歷;
5.ListedList的特點
- 動態(tài)性:沒有固定的大小限制,大小可動態(tài)變化;
- 插入或刪除高效:在插入和刪除時,只需修改相關節(jié)點即可,時間復雜度為O(1);
- 順序訪問:只能順序訪問節(jié)點,效率較低,時間復雜度為O(n);
- 存儲結構:由一系列節(jié)點組成,每個節(jié)點包含數(shù)據(jù)域和指針域;
- 通用性:可以存儲不同數(shù)據(jù)。
6.LinkedList優(yōu)缺點
1.LinkedList優(yōu)點:
- 動態(tài)性強:節(jié)點分散存儲,不受連續(xù)空間的限制;
- 插入或刪除高效:在插入和刪除時,只需修改相關節(jié)點即可,時間復雜度為O(1);
- 可擴性好:可方便的增加和減少節(jié)點的數(shù)量;
2.LinkedList缺點:
- 隨機訪問效率低:只能順序訪問節(jié)點,效率較低,時間復雜度為O(n);
- 額外空間開銷大:除了存儲數(shù)據(jù)本身,每個節(jié)點還要存儲額外的指針信息,內存利用率低;
- 數(shù)據(jù)存儲不連續(xù):不利于有效存儲,導致數(shù)據(jù)訪問慢;
四、ArrayList與LinkedList的區(qū)別
| 不同點 | ArrayList | LinkedList |
| 數(shù)據(jù)結構 | 邏輯上和物理上都是連續(xù)的 | 在邏輯上連續(xù),物理上不連續(xù) |
| 隨機訪問 | 隨機訪問效率快, 時間復雜度為O(1) | 隨機訪問效率慢, 時間復雜度為O(n) |
| 插入或刪除 | 效率慢, 時間復雜度為O(n) | 效率快, 時間復雜度為O(1) |
| 容量 | 空間不夠需要擴容 | 沒有容量限制 |
| 內存占用 | 內存利用相對高效 | 內存利用率低 |
| 應用場景 | 元素訪問+高效存儲 | 插入和刪除頻繁 |
總結
到此這篇關于Java中ArrayList與LinkedList的使用及區(qū)別的文章就介紹到這了,更多相關Java ArrayList與LinkedList詳解內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot+本地消息表實現(xiàn)分布式最終一致性
本文主要介紹了SpringBoot+本地消息表實現(xiàn)分布式最終一致性,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2026-02-02
Spring?Boot使用Hutool快速集成驗證碼的兩種方案
驗證碼作為一種簡單而有效的身份驗證手段,被廣泛應用于各種在線服務中,這篇文章主要介紹了Spring?Boot使用Hutool快速集成驗證碼的兩種方案,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2026-02-02
Spring接口版本控制方案及RequestMappingHandlerMapping接口介紹(最新推薦)
RequestMappingHandlerMapping接口是Spring MVC中的一個核心組件,負責處理請求映射和處理器的匹配這篇文章主要介紹了Spring接口版本控制方案及RequestMappingHandlerMapping接口介紹,需要的朋友可以參考下2024-07-07






