List介紹

什么是List

  • 在集合框架中,List是一個接口,繼承自Collection

  • Collection也是一個接口,該接口中規范了后序容器中常用的一些方法

  • Iterable也是一個接口,表示實現該接口的類是可以逐個元素進行遍歷的,具體如下:

List的官方文檔

List (Java Platform SE 8 )List (Java Platform SE 8 )

站在數據結構的角度來看,List就是一個線性表,即n個具有相同類型元素的有限序列,在該序列上可以執行增刪改查以及變量等操作
?

List常見接口介紹

List接口包括Collection接口的所有方法。 這是因為Collection是List的超級接口。

Collection接口中還提供了一些常用的List接口方法:

  • add() - 將元素添加到列表

  • addAll() - 將一個列表的所有元素添加到另一個

  • get() - 有助于從列表中隨機訪問元素

  • iterator() - 返回迭代器對象,該對象可用于順序訪問列表的元素

  • set() - 更改列表的元素

  • remove() - 從列表中刪除一個元素

  • removeAll() - 從列表中刪除所有元素

  • clear() - 從列表中刪除所有元素(比removeAll()效率更高)

  • size() - 返回列表的長度

  • toArray() - 將列表轉換為數組

  • contains() -? 如果列表包含指定的元素,則返回true

List的使用

注意:List是個接口,并不能直接用來實例化。 如果要使用,必須去實例化List的實現類。在集合框架中,ArrayList和LinkedList都實現了List接口

線性表

線性表(linear list)是n個具有相同特性的數據元素的有限序列。 線性表是一種在實際中廣泛使用的數據結 構,常見的線性表:順序表、鏈表、棧、隊列...

線性表在邏輯上是線性結構,也就說是連續的一條直線。但是在物理結構上并不一定是連續的,線性表在物理上存儲時,通常以數組和鏈式結構的形式存儲

順序表

順序表是用一段物理地址連續的存儲單元依次存儲數據元素的線性結構,一般情況下采用數組存儲。在數組上完成 數據的增刪查改

接口的實現

public class SeqList {private int[] array;private int size;// 默認構造方法SeqList() {}// 將順序表的底層容量設置為initcapacitySeqList(int initcapacity) {}// 新增元素,默認在數組最后新增public void add(int data) {}// 在 pos 位置新增元素public void add(int pos, int data) {}// 判定是否包含某個元素public boolean contains(int toFind) {return true;}// 查找某個元素對應的位置public int indexOf(int toFind) {return -1;}// 獲取 pos 位置的元素public int get(int pos) {return -1;}// 給 pos 位置的元素設為 valuepublic void set(int pos, int value) {}//刪除第一次出現的關鍵字keypublic void remove(int toRemove) {}// 獲取順序表長度public int size() {return 0;}// 清空順序表public void clear() {}// 打印順序表,注意:該方法并不是順序表中的方法,為了方便看測試結果給出的public void display() {}
}

ArrayList的簡介

在集合框架中,ArrayList是一個普通的類,實現了List接口,具體框架圖如下:

ArrayList使用

說明

  • ArrayList是以泛型方式實現的,使用時必須要先實例化
  • ArrayList實現了RandomAccess接口,表明ArrayList支持隨機訪問
  • ArrayList實現了Cloneable接口,表明ArrayList是可以clone的
  • ArrayList實現了Serializable接口,表明ArrayList是支持序列化的
  • 和Vector不同,ArrayList不是線程安全的,在單線程下可以使用,在多線程中可以選擇Vector或者 CopyOnWriteArrayList
  • ArrayList底層是一段連續的空間,并且可以動態擴容,是一個動態類型的順序表

ArrayList使用

ArrayList的構造

  • ArrayList() 無參構造
  • ArrayList(Collection c) 利用其他 Collection 構建 ArrayList
  • ArrayList(int initialCapacity) 指定順序表初始容量
public static void main(String[] args) {
// ArrayList創建,推薦寫法
// 構造一個空的列表List<Integer> list1 = new ArrayList<>();
// 構造一個具有10個容量的列表List<Integer> list2 = new ArrayList<>(10);list2.add(1);list2.add(2);list2.add(3);
// list2.add("hello"); // 編譯失敗,List<Integer>已經限定了,list2中只能存儲整形元素
// list3構造好之后,與list中的元素一致ArrayList<Integer> list3 = new ArrayList<>(list2);
// 避免省略類型,否則:任意類型的元素都可以存放,使用時將是一場災難List list4 = new ArrayList();list4.add("111");list4.add(100);
}
public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("JavaSE");list.add("JavaWeb");list.add("JavaEE");list.add("JVM");list.add("測試課程");System.out.println(list);// 獲取list中有效元素個數System.out.println(list.size());// 獲取和設置index位置上的元素,注意index必須介于[0, size)間System.out.println(list.get(1));list.set(1, "JavaWEB");System.out.println(list.get(1));// 在list的index位置插入指定元素,index及后續的元素統一往后搬移一個位置list.add(1, "Java數據結構");System.out.println(list);// 刪除指定元素,找到了就刪除,該元素之后的元素統一往前搬移一個位置list.remove("JVM");System.out.println(list);// 刪除list中index位置上的元素,注意index不要超過list中有效元素個數,否則會拋出下標越界異常list.remove(list.size() - 1);System.out.println(list);// 檢測list中是否包含指定元素,包含返回true,否則返回falseif (list.contains("測試課程")) {list.add("測試課程");}// 查找指定元素第一次出現的位置:indexOf從前往后找,lastIndexOf從后往前找list.add("JavaSE");System.out.println(list.indexOf("JavaSE"));System.out.println(list.lastIndexOf("JavaSE"));// 使用list中[0, 4)之間的元素構成一個新的SubList返回,但是和ArrayList共用一個elementData數組List<String> ret = list.subList(0, 4);System.out.println(ret);list.clear();System.out.println(list.size());
}

ArrayList的遍歷

ArrayList 可以使用三方方式遍歷:for循環+下標、foreach、使用迭代器

public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);// 使用下標+for遍歷for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i) + " ");}System.out.println();// 借助foreach遍歷for (Integer integer : list) {System.out.print(integer + " ");}System.out.println();Iterator<Integer> it = list.listIterator();while (it.hasNext()) {System.out.print(it.next() + " ");}System.out.println();
}

注意:

  • ArrayList最長使用的遍歷方式是:for循環+下標 以及 foreach
  • 迭代器是設計模式的一種

ArrayList的擴容機制

下面代碼有缺陷嗎?為什么?

public static void main(String[] args) {List<Integer> list = new ArrayList<>();for (int i = 0; i < 100; i++) {list.add(i);}
}

ArrayList是一個動態類型的順序表,即:在插入元素的過程中會自動擴容。

以下是ArrayList源碼中擴容方式:
transient Object[] elementData; // non-private to simplify nested class access
private int size;
//構造方法
public ArrayList( int initialCapacity){if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {this.elementData = EMPTY_ELEMENTDATA;} else {throw new IllegalArgumentException("Illegal Capacity: " +initialCapacity);}
}
public void trimToSize() {modCount++;if (size < elementData.length) {elementData = (size == 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);}
}public void ensureCapacity(int minCapacity) {if (minCapacity > elementData.length&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA&& minCapacity <= DEFAULT_CAPACITY)) {modCount++;grow(minCapacity);}
}private Object[] grow(int minCapacity) {int oldCapacity = elementData.length;if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {int newCapacity = ArraysSupport.newLength(oldCapacity,minCapacity - oldCapacity, /* minimum growth */oldCapacity >> 1           /* preferred growth */);return elementData = Arrays.copyOf(elementData, newCapacity);} else {return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];}}
/*
這段代碼是Java語言編寫的,它定義了一個名為`grow`的方法,這個方法的作用是擴容一個數組,使其能夠容納更多的元素。這個方法是私有的,意味著它只能在定義它的類內部被調用。下面是對這個方法的逐行解釋:1. `private Object[] grow(int minCapacity) {`:定義了一個私有方法`grow`,它接受一個整型參數`minCapacity`,表示數組需要擴容到的最小容量,并返回一個`Object`類型的數組。2. `int oldCapacity = elementData.length;`:獲取當前數組`elementData`的容量,并將其存儲在變量`oldCapacity`中。3. `if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {`:檢查當前數組是否已經有容量(即不是默認的空數組)。`DEFAULTCAPACITY_EMPTY_ELEMENTDATA`可能是一個常量,表示默認的空數組。4. `int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, oldCapacity >> 1);`:調用`ArraysSupport.newLength`方法來計算新的容量。這個方法的參數包括:- `oldCapacity`:當前數組的容量。- `minCapacity - oldCapacity`:需要增加的最小容量。- `oldCapacity >> 1`:推薦的增長量,這里使用了右移操作符`>>`,相當于將`oldCapacity`除以2。5. `return elementData = Arrays.copyOf(elementData, newCapacity);`:使用`Arrays.copyOf`方法將當前數組`elementData`復制到一個新的數組中,新數組的容量為`newCapacity`。這個方法會返回新的數組,并且更新`elementData`引用指向這個新數組。6. `} else {`:如果當前數組是空的(即沒有容量),則執行else塊中的代碼。7. `return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];`:在這種情況下,創建一個新的`Object`數組,其容量是`DEFAULT_CAPACITY`和`minCapacity`中的最大值。`DEFAULT_CAPACITY`可能是一個定義了默認初始容量的常量。8. `}`:方法的結束。總的來說,這個方法的目的是確保`elementData`數組有足夠的容量來存儲至少`minCapacity`個元素。如果當前數組的容量已經足夠,它將按照一定的增長策略(至少是當前容量的一半)來擴容。如果當前數組是空的,它將創建一個新的數組,其容量至少為`DEFAULT_CAPACITY`或`minCapacity`中的較大值。*/

總結

  • 檢測是否真正需要擴容,如果是調用grow準備擴容
  • 預估需要庫容的大小 初步預估按照1.5倍大小擴容 如果用戶所需大小超過預估1.5倍大小,則按照用戶所需大小擴容 真正擴容之前檢測是否能擴容成功,防止太大導致擴容失敗
  • 使用copyOf進行擴容

ArrayList的問題及思考

  1. ArrayList底層使用連續的空間,任意位置插入或刪除元素時,需要將該位置后序元素整體往前或者往后搬 移,故時間復雜度為O(N)
  2. 增容需要申請新空間,拷貝數據,釋放舊空間。會有不小的消耗
  3. 增容一般是呈2倍的增長,勢必會有一定的空間浪費。例如當前容量為100,滿了以后增容到200,我們再繼 續插入了5個數據,后面沒有數據插入了,那么就浪費了95個數據空間

如何解決上述問題?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/81159.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/81159.shtml
英文地址,請注明出處:http://en.pswp.cn/web/81159.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入理解API:從概念到實戰

引言 在現代軟件開發中&#xff0c;API&#xff08;Application Programming Interface&#xff09;無處不在。無論是調用第三方服務、訪問操作系統功能&#xff0c;還是使用編程語言的標準庫&#xff0c;API 都扮演著關鍵角色。但對于許多初學者來說&#xff0c;API 仍然是一…

織夢dedecms登錄后臺出現Safe Alert Request Error step 2

今天一個客戶在安裝織夢dedecms時候&#xff0c;安裝完成后登錄后臺就出現“Safe Alert Request Error step 2”&#xff0c;常用dedecms的朋友都知道&#xff0c;這是織夢的安全機制&#xff0c;在程序覺得有sql注入等攻擊時候&#xff0c;會有這種提示。 1、起初我以為是文件…

BLIP3-o:理解和生成統一的多模態模型

文章目錄 研究背景BLIP3-o 框架3個關鍵問題BLIP3-o模型總結 paper link: https://arxiv.org/pdf/2505.09568from saleforce research 研究背景 隨著gpt4o圖像生成和編輯的應用火爆&#xff0c;如何構造能夠同時處理圖像理解和生成任務的統一多模態模型&#xff0c;成為研究的…

練習小項目7:天氣狀態切換器

&#x1f9e0; 項目目標&#xff1a; 點擊按鈕切換不同天氣狀態&#xff0c;背景或圖標隨之變化。 ? 功能描述&#xff1a; 顯示當前天氣&#xff08;如&#xff1a;?? 晴天 / ?? 多云 / &#x1f327;? 雨天&#xff09; 點擊“切換天氣”按鈕&#xff0c;每點擊一次…

esp32 lvgl9.2版本,透明底色圖片的,透明部分被渲染成黑色,不隨背景顏色變化解決辦法

在lvgl圖片轉換工具時&#xff0c;指定轉換格式為ARGB8888 代指Alpha RGB RGB565&#xff08;不支持 Alpha&#xff09;&#xff0c;透明像素會被解釋為黑色。改用 ARGB8888。 有問題的 轉換為ARGB8888后的

AI智能分析網關V4區域入侵檢測算法:全功能覆蓋,多場景守護安防安全

一、方案背景? 在當今社會&#xff0c;安全需求日益增長&#xff0c;傳統安防監控系統因效率低、精準度不足等問題&#xff0c;已無法滿足現代安全防范的要求。AI智能分析網關V4區域入侵檢測算法憑借其先進的人工智能技術&#xff0c;能夠實時、精準地識別區域內的異常入侵行…

Phantom 視頻生成的流程

Phantom 視頻生成的流程 flyfish Phantom 視頻生成的實踐 Phantom 視頻生成的流程 Phantom 視頻生成的命令 Wan2.1 圖生視頻 支持批量生成 Wan2.1 文生視頻 支持批量生成、參數化配置和多語言提示詞管理 Wan2.1 加速推理方法 Wan2.1 通過首尾幀生成視頻 AnyText2 在圖片里玩…

瑞薩單片機筆記

1.CS for CC map文件中顯示變量地址 Link Option->List->Output Symbol information 2.FDL庫函數 pfdl_status_t R_FDL_Write(pfdl_u16 index, __near pfdl_u08* buffer, pfdl_u16 bytecount) pfdl_status_t R_FDL_Read(pfdl_u16 index, __near pfdl_u08* buffer, pfdl_…

uniapp+ts 多環境編譯

1. 創建項目 npx degit dcloudio/uni-preset-vue#vite-ts [項目名稱] 2.創建env目錄 多環境配置文件命名為.env.別名 添加index.d.ts interface ImportMetaEnv{readonly VITE_ENV:string,readonly UNI_PLATFORM:string,readonly VITE_APPID:string,readonly VITE_NAME:stri…

英語學習5.24

make informed decisions 表示“做出明智的決定”&#xff0c;是一個常用的固定搭配&#xff0c;常用于議論文中。 …to make informed decisions. 為了做出明智的決定&#xff08;表示目的的動詞不定式&#xff09;。 We need accurate data to make informed decisions. Ci…

【Qt】QImage::Format

QImage::Format 是 Qt 中用于指定圖像像素數據格式的枚舉類型。它決定了圖像如何存儲顏色信息和透明度&#xff08;如果有&#xff09;。選擇合適的 Format 對性能、內存占用以及是否支持某些特性&#xff08;如透明通道&#xff09;有重要影響。 常見的 QImage::Format 枚舉值…

算法筆記·數學·歐拉函數

題目&#xff1a;&#xff08;AcWing&#xff09; 給定 n 個正整數 ai&#xff0c;請你求出每個數的歐拉函數。 歐拉函數的定義 1~N 中與 N 互質的數的個數被稱為歐拉函數&#xff0c;記為 ?(N)。 若在算數基本定理中&#xff0c;N&#xff0c;則&#xff1a; ?(N) N 輸入…

深入理解Redis線程模型

Redis數據 redis數據保存在內存&#xff0c;但是會持久化到硬盤 Redis線程 Redis的整體線程模型可以簡單解釋為 客戶端多線程&#xff0c;服務端單線程。也就是可以多個客戶端同時連接。 核心線程模型&#xff1a;單線程 多路復用 Redis 的主線程負責處理所有客戶端請求&a…

「Python教案」輸入輸出函數的使用

課程目標 1&#xff0e;知識目標 能使用input()輸入函數和print()輸出函數實現人機之間的交互。能夠合理的確定輸入數據的數據類型&#xff0c;并進行數據類型轉換。能夠使用格式化字符串&#xff08;f-string&#xff09;將數據動態輸出。 2&#xff0e;能力目標 能夠使用…

醫療影像中,DICOM點云、三角面片實體混合渲染(VR)

此文章&#xff0c;涉及到專業性比較強&#xff0c;所以&#xff0c;大部分的內容&#xff0c;基本上都是示例代碼的形式出現。以下的技術路徑&#xff0c;完全經過實踐驗證&#xff0c;并且效果很好&#xff0c;可以放心使用。 1 概述 在醫學影像中&#xff0c;對DICOM的渲染…

【C/C++】線程狀態以及轉換

文章目錄 線程狀態以及轉換1 基本狀態1.1 新建&#xff08;New&#xff09;1.2 就緒&#xff08;Ready / Runnable&#xff09;1.3 運行中&#xff08;Running&#xff09;1.4 阻塞/等待&#xff08;Blocked / Waiting / Sleeping&#xff09;1.5 掛起&#xff08;Suspended&am…

Python與自動駕駛數據集處理:構建智能駕駛的基石

Python與自動駕駛數據集處理:構建智能駕駛的基石 在自動駕駛技術的快速發展中,數據始終是最核心的驅動力。自動駕駛系統依賴于大量的傳感器數據(激光雷達、攝像頭、GPS等),通過深度學習算法不斷優化決策,使車輛能夠自主感知、理解道路環境并做出合理決策。而 Python 作為…

【菜狗work前端】小程序加if判斷時不及時刷新 vs Web

零、前提&#xff1a; 實現input輸入數字不大于10000&#xff08;需要配合typenumber&#xff0c;maxlength5&#xff0c;這里沒寫&#xff09; 一、探究代碼&#xff1a; <input v-model"model1" input"changeModel1" placeholder"請輸入拒收件…

【Netty】- NIO基礎2

阻塞模式 客戶端代碼 public class Client {public static void main(String[] args) throws IOException {SocketChannel sc SocketChannel.open();sc.connect(new InetSocketAddress("localhost", 8080));// sc.write(Charset.defaultCharset().encode("he…

【WebRTC】源碼更改麥克風權限

WebRTC源碼更改麥克風權限 倉庫: https://webrtc.googlesource.com/src.git分支: guyl/m125節點: b09c2f83f85ec70614503d16e4c530484eb0ee4f