java集合類源碼分析之List(一)

来源:http://www.cnblogs.com/Wilange/archive/2017/10/06/7631933.html
-Advertisement-
Play Games

首先分析一下集合與數組的區別:1.java中的數組一般用於存儲基本數據類型,而且是靜態的,即長度固定不變,這就不適用於元素個數未知的情況;2.集合只能用於存儲引用類型,並且長度可變,適用於大多數情況,可用toArray()方法轉換成數組。 java語言提供了多種集合類的介面,如List、Set、Ma ...


  首先分析一下集合與數組的區別:1.java中的數組一般用於存儲基本數據類型,而且是靜態的,即長度固定不變,這就不適用於元素個數未知的情況;2.集合只能用於存儲引用類型,並且長度可變,適用於大多數情況,可用toArray()方法轉換成數組。

java語言提供了多種集合類的介面,如List、Set、Map等。這裡首先從List開始分析,其實現類有ArrayList、LinkedList、Vector(Stack),下麵就從它們的源代碼開始:

1.ArrayList(數組列表)

顧名思義,這是一種以數組形式進行存儲的列表,所以其優點是便於隨機訪問,而在插入和刪除操作時效率較低

  • 構造方法(三種):

1.public ArrayList(int initialCapacity)  指定初始列表的容量,當容量不夠時會自動進行擴容

2.public ArrayList()  空的構造方法

3.public ArrayList(Collection<? extends E> c)  初始化列表元素,傳入參數為一個集合類的對象

1         ArrayList<String> arrayList1 = new ArrayList<String>(3);    //初始化ArrayList容量大小
2         arrayList1.add("A");
3         arrayList1.add("B");
4         arrayList1.add("C");
5         ArrayList<String> arrayList2 = new ArrayList<String>(arrayList1);    //初始化ArrayList元素
6         System.out.println(arrayList2);    //[A, B, C]
View Code
  • 插入元素(add)

1.在列表尾部插入 add(E e)

1  public boolean add(E e) {
2         ensureCapacityInternal(size + 1);  // Increments modCount!!
3         elementData[size++] = e;
4         return true;
5     }
View Code

2.在列表指定位置插入 add(int index, E element)

1 public void add(int index, E element) {
2         rangeCheckForAdd(index);
3 
4         ensureCapacityInternal(size + 1);  // Increments modCount!!
5         System.arraycopy(elementData, index, elementData, index + 1,
6                          size - index);
7         elementData[index] = element;
8         size++;
9     }
View Code

3.在列表尾部插入一個子集 addAll(Collection<? extends E> c)

1     public boolean addAll(Collection<? extends E> c) {
2         Object[] a = c.toArray();
3         int numNew = a.length;
4         ensureCapacityInternal(size + numNew);  // Increments modCount
5         System.arraycopy(a, 0, elementData, size, numNew);
6         size += numNew;
7         return numNew != 0;
8     }
View Code

4.在列表的指定位置插入一個子集 addAll(int index, Collection<? extends E> c)

 1     public boolean addAll(int index, Collection<? extends E> c) {
 2         rangeCheckForAdd(index);
 3 
 4         Object[] a = c.toArray();
 5         int numNew = a.length;
 6         ensureCapacityInternal(size + numNew);  // Increments modCount
 7 
 8         int numMoved = size - index;
 9         if (numMoved > 0)
10             System.arraycopy(elementData, index, elementData, index + numNew,
11                              numMoved);
12 
13         System.arraycopy(a, 0, elementData, index, numNew);
14         size += numNew;
15         return numNew != 0;
16     }
View Code

觀察源碼可知,在指定位置插入元素其實是通過arraycopy()方法來實現的,即是將原數組複製到目標數組,因而效率較低

應用示例:

1         ArrayList<String> arrayList1 = new ArrayList<String>(3);    //初始化ArrayList容量大小
2         arrayList1.add("A");
3         arrayList1.add("B");
4         arrayList1.add("C");
5         arrayList1.add("D");
6         System.out.println(arrayList1);    //[A, B, C, D]
7         arrayList1.add(0, "E");
8         System.out.println(arrayList1); //[E, A, B, C, D]
View Code
  • 查找元素

1.查找指定位置的元素 get(int index)

2.查找指定元素的位置 indexOf(Object o)、lastIndexOf(Object o)

3.查找列表中是否包含指定元素 contains(Object o)

1  public boolean contains(Object o) {
2         return indexOf(o) >= 0;
3     }
View Code

由於ArrayList以數組方式實現,自帶索引,所以便於隨機查找

  • 修改元素

修改指定位置的元素 set(int index, E element)

1         ArrayList<String> arrayList1 = new ArrayList<String>(3);    //初始化ArrayList容量大小
2         arrayList1.add("A");
3         arrayList1.add("B");
4         arrayList1.add("C");
5         arrayList1.add("D");
6         System.out.println(arrayList1); //[A, B, C, D]
7         arrayList1.set(0, "X");
8         System.out.println(arrayList1); //[X, B, C, D]
View Code

由於ArrayList以數組方式實現,自帶索引,所以便於隨機修改

  • 刪除元素

1.刪除指定位置的元素 remove(int index)

 1     public E remove(int index) {
 2         rangeCheck(index);
 3 
 4         modCount++;
 5         E oldValue = elementData(index);
 6 
 7         int numMoved = size - index - 1;
 8         if (numMoved > 0)
 9             System.arraycopy(elementData, index+1, elementData, index,
10                              numMoved);
11         elementData[--size] = null; // clear to let GC do its work
12 
13         return oldValue;
14     }
View Code

2.刪除指定元素 remove(Object o)

 1     public boolean remove(Object o) {
 2         if (o == null) {
 3             for (int index = 0; index < size; index++)
 4                 if (elementData[index] == null) {
 5                     fastRemove(index);
 6                     return true;
 7                 }
 8         } else {
 9             for (int index = 0; index < size; index++)
10                 if (o.equals(elementData[index])) {
11                     fastRemove(index);
12                     return true;
13                 }
14         }
15         return false;
16     }
View Code

3.清空列表 clear()

1     public void clear() {
2         modCount++;
3 
4         // clear to let GC do its work
5         for (int i = 0; i < size; i++)
6             elementData[i] = null;
7 
8         size = 0;
9     }
View Code

從源碼中我們可以知道,刪除元素時也是通過arraycopy()方法,將原數組複製到目標數組,因而效率較低

應用示例:

 1         ArrayList<String> arrayList1 = new ArrayList<String>(3);    //初始化ArrayList容量大小
 2         arrayList1.add("A");
 3         arrayList1.add("B");
 4         arrayList1.add("C");
 5         arrayList1.add("D");
 6         arrayList1.remove(0);
 7         System.out.println(arrayList1);    //[B, C, D]
 8         arrayList1.remove("D");
 9         System.out.println(arrayList1);    //[B, C]
10         arrayList1.clear();
11         System.out.println(arrayList1.isEmpty());    //true
View Code

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首先我們來瞭解下python中的進程,線程以及協程! 從電腦硬體角度: 電腦的核心是CPU,承擔了所有的計算任務。一個CPU,在一個時間切片里只能運行一個程式。 從操作系統的角度: 進程和線程,都是一種CPU的執行單元。 進程:表示一個程式的上下文執行活動(打開、執行、保存...) 線程:進程執 ...
  • matplotlib學習之函數積分圖 ...
  • 關於split()函數的簡單使用,分隔符在字元串中的位置不同,分割的不同情況。 ...
  • 單例模式顧名思義,就是只有一個實例,作為對象的創建模式,單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。 單例模式的三個要點: 1.某個類只能有一個實例。 2.必須自行創建這個實例。 3.必須自行向整個系統提供這個實例。 為什麼要使用PHP單例模式? 1.PHP的應用有一個 ...
  • /* 需求:演示一個Hello World的Java小程式 思路: 1.定義一個類。因為Java程式都是定義在類中,Java程式都是以類的形式存在的,類的形式其實就是位元組碼的最終體現 2.定義一個主函數。可以讓該類可以獨立運行。 3.使用輸出語句。可以讓程式的運行結果顯示在控制臺上。 步驟: 1.定 ...
  • 1、MVC:非Java獨有,所有的B/S的結構都在使用它。 M——Model模式(自己寫代碼) V——View 視圖(jsp) C——Controller 控制器(Servlet) 2、JavaWeb三層框架 Web層-->與Web相關的內容(Servlet,JSP,Servlet相關API:req ...
  • 一、創建自定義標簽基本步驟 1、步驟 標簽處理類(標簽也是一個對象,那麼就需要先有類!) tld文件,它是一個xml 頁面中使用<%@taglib%>來指定tld文件的位置 2、標簽處理類 SimpleTag介面 void doTag():每次執行標簽時都會調用這個方法; JspTag getPar ...
  • Python 協程爬取妹子圖~~~ async aiohttp scrapy ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...