深入理解ArrayList:從Java原生實現到手寫一個ArrayList

Java原生ArrayList解析

基本結構

Java的ArrayList是基于數組實現的動態列表,主要特點包括:

  1. 動態擴容:當元素數量超過當前容量時,自動擴容(通常增加50%)

  2. 快速隨機訪問:通過索引訪問元素的時間復雜度為O(1)

  3. 有序集合:保持元素的插入順序

核心實現機制

// JDK中的關鍵字段
transient Object[] elementData; // 存儲元素的數組緩沖區
private int size; // 列表中實際元素數量
private static final int DEFAULT_CAPACITY = 10; // 默認初始容量

擴容機制

private void grow(int minCapacity) {int oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5倍擴容if (newCapacity - minCapacity < 0)newCapacity = minCapacity;elementData = Arrays.copyOf(elementData, newCapacity);
}

時間復雜度分析

  • 訪問元素:O(1)

  • 添加元素(尾部):平均O(1),最壞O(n)(需要擴容)

  • 插入/刪除元素(非尾部):O(n)(需要移動元素)

自定義MyArrayList實現

package com.zsy;import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;/*** 自定義動態數組實現,支持泛型元素存儲和基本列表操作** <p>本實現提供類似Java ArrayList的核心功能,包括:</p>* <ul>*   <li>動態擴容機制(默認初始容量10,按2倍擴容)</li>*   <li>支持索引訪問和修改</li>*   <li>提供元素遍歷功能</li>*   <li>實現基本的增刪改查操作</li>* </ul>** <p><b>特性說明:</b></p>* <ul>*   <li>時間復雜度:隨機訪問O(1),插入/刪除平均O(n)</li>*   <li>空間復雜度:O(n)</li>*   <li><b>非線程安全</b> - 多線程環境下需要外部同步</li>* </ul>** @param <E> 列表元素類型* @author zsy* @see List*/
public class MyArrayList<E> implements List<E> {/*** 當前列表中實際存儲的元素數量*/private int size;/*** 列表當前分配的存儲容量*/private int capacity;/*** 存儲列表元素的數組緩沖區*/private Object[] elements;/*** 構造一個初始容量為10的空列表*/public MyArrayList() {this(10);}/*** 構造具有指定初始容量的空列表** @param initialCapacity 初始容量* @throws IllegalArgumentException 如果初始容量為負數*/public MyArrayList(int initialCapacity) {if (initialCapacity < 0) {throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);}this.capacity = initialCapacity;this.elements = new Object[initialCapacity];}/*** 將指定元素追加到列表末尾** @param element 要添加的元素*/@Overridepublic void add(E element) {ensureCapacity();elements[size++] = element;}/*** 在列表的指定位置插入指定元素** @param element 要插入的元素* @param index 插入位置的索引* @throws IndexOutOfBoundsException 如果索引超出范圍*/@Overridepublic void add(E element, int index) {rangeCheckForAdd(index);ensureCapacity();System.arraycopy(elements, index, elements, index + 1, size - index);elements[index] = element;size++;}/*** 移除并返回列表中指定位置的元素** @param index 要移除元素的索引* @return 被移除的元素* @throws IndexOutOfBoundsException 如果索引超出范圍*/@Overridepublic E remove(int index) {rangeCheck(index);E oldValue = elementData(index);int numMoved = size - index - 1;if (numMoved > 0) {System.arraycopy(elements, index + 1, elements, index, numMoved);}elements[--size] = null; // 清除引用,幫助GCreturn oldValue;}/*** 從列表中移除首次出現的指定元素** @param element 要移除的元素* @return 如果列表包含該元素則返回true*/@Overridepublic boolean remove(E element) {for (int i = 0; i < size; i++) {if (Objects.equals(element, elements[i])) {remove(i);return true;}}return false;}/*** 替換列表中指定位置的元素** @param index 要替換元素的索引* @param element 要存儲的元素* @return 先前在指定位置的元素* @throws IndexOutOfBoundsException 如果索引超出范圍*/@Overridepublic E set(int index, E element) {rangeCheck(index);E oldValue = elementData(index);elements[index] = element;return oldValue;}/*** 返回列表中指定位置的元素** @param index 要返回元素的索引* @return 列表中指定位置的元素* @throws IndexOutOfBoundsException 如果索引超出范圍*/@Overridepublic E get(int index) {rangeCheck(index);return elementData(index);}/*** 返回列表中的元素數量** @return 列表中的元素數量*/@Overridepublic int size() {return size;}/*** 返回此列表中元素的迭代器** @return 按適當順序包含此列表中所有元素的迭代器*/@Overridepublic Iterator<E> iterator() {return new ArrayListIterator();}// ========== 私有輔助方法 ==========/*** 確保列表有足夠的容量容納新元素*/private void ensureCapacity() {if (size == capacity) {resize();}}/*** 擴容列表存儲容量*/private void resize() {int newCapacity = capacity * 2;Object[] newElements = new Object[newCapacity];System.arraycopy(elements, 0, newElements, 0, size);elements = newElements;capacity = newCapacity;}/*** 檢查索引是否在有效范圍內*/private void rangeCheck(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}}/*** 檢查添加操作的索引是否在有效范圍內*/private void rangeCheckForAdd(int index) {if (index < 0 || index > size) {throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}}/*** 構造索引越界異常信息*/private String outOfBoundsMsg(int index) {return "Index: " + index + ", Size: " + size;}/*** 獲取指定位置的元素(帶類型轉換)*/@SuppressWarnings("unchecked")private E elementData(int index) {return (E) elements[index];}// ========== 內部迭代器實現 ==========/*** 列表迭代器實現*/private class ArrayListIterator implements Iterator<E> {/*** 當前迭代位置*/private int cursor;/*** 檢查是否還有更多元素可迭代** @return 如果迭代有更多元素則返回true*/@Overridepublic boolean hasNext() {return cursor != size;}/*** 返回迭代中的下一個元素** @return 迭代中的下一個元素* @throws NoSuchElementException 如果迭代沒有更多元素*/@Overridepublic E next() {if (cursor >= size) {throw new NoSuchElementException();}return elementData(cursor++);}}
}

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

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

相關文章

【力扣 簡單 C】206. 反轉鏈表

目錄 題目 解法一&#xff1a;迭代 解法二&#xff1a;遞歸 題目 解法一&#xff1a;迭代 struct ListNode* reverse(struct ListNode* head) {struct ListNode* retHead NULL;while (head){struct ListNode* nextNode head->next;head->next retHead;retHead he…

明代大模型:智能重構下的文明再發現

引言&#xff1a;當紫禁城遇見生成式AI 一幅動態的《紫禁城圖卷》正通過全息投影技術演繹永樂年間的宮廷盛景。這個虛實交融的場景&#xff0c;恰似明代大模型技術的隱喻——以人工智能為紐帶&#xff0c;連接起永樂盛世的恢弘氣象與數字時代的文明重構。作為人工智能與歷史學…

推薦使用的Unity插件(行為樹Behavior )

在 Unity 6.0 中使用 Behavior Designer 行為樹插件開發 AI 系統&#xff0c;需結合其核心節點設計、變量管理和代碼控制。以下是詳細指南&#xff0c;整合了最新版本的最佳實踐&#xff1a; &#x1f6e0;? 1. 安裝與基礎配置 安裝插件 通過 Unity Asset Store 安裝 “Behav…

107. Java 繼承 - 總結:方法重寫與隱藏

文章目錄 107. Java 繼承 - 總結&#xff1a;方法重寫與隱藏**詳細解釋&#xff1a;****方法重載** **總結** 107. Java 繼承 - 總結&#xff1a;方法重寫與隱藏 在 Java 中&#xff0c;定義與超類中的方法具有相同簽名的方法時&#xff0c;不同類型的方法之間會有不同的行為。…

Spring Cloud使用Eureka調用接口,超時設置(二)

在 Spring Cloud 微服務架構中&#xff0c;當同時配置了 Ribbon 和 Feign 的超時時間時&#xff0c;Feign 的配置優先級高于 Ribbon。具體規則和底層邏輯如下&#xff1a; ?? 1. 配置優先級規則 Feign 顯式配置 > Ribbon 配置 若在 Feign 中顯式設置了超時時間&#xff0…

iOS-SM3加密算法N種集成

近期的一個項目需要用到SM3加密算法&#xff0c;需要在iOS中使用Objective-C實現SM3國密加密算法。 SM3&#xff1a;是中國國家密碼管理局發布的密碼雜湊算法標準&#xff0c;適用于商用密碼應用中的數字簽名和驗證、消息認證碼的生成與驗證以及隨機數的生成等 由于iOS系統并未…

[逆向工程]什么是TEB 與 PEB(二十九)

[逆向工程]什么是TEB 與 PEB(二十九) 一、引言:為什么需要了解 TEB/PEB? 在 Windows 系統開發、調試或逆向工程中,TEB(Thread Environment Block) 和 PEB(Process Environment Block) 是理解程序執行機制的關鍵。它們如同進程與線程的“身份證”,存儲了從內存布局到…

逆向分析貝殼網人機驗證JS加密邏輯

引言 在數據爬取和自動化測試過程中&#xff0c;人機驗證&#xff08;如滑塊、點選、短信驗證等&#xff09;是常見的反爬手段。貝殼網&#xff08;ke.com&#xff09;作為國內領先的房產平臺&#xff0c;其人機驗證機制較為復雜&#xff0c;涉及前端JS加密、動態Token、行為檢…

Vue3 + Element Plus中el-table加載狀態分析

在 Vue 3 中&#xff0c;當 onMounted 鉤子被觸發時&#xff0c;父組件的 DOM 已經掛載完成&#xff0c;但子組件&#xff08;如 el-table&#xff09;可能尚未完成其內部渲染。具體分析如下&#xff1a; 1. onMounted 的執行時機 父組件掛載完成&#xff1a;onMounted 表示當前…

OpenCV圖像拼接技術詳解:從特征匹配到全景合成

本文將詳細介紹如何使用OpenCV實現兩幅圖像的自動拼接&#xff0c;涵蓋特征提取、單應性矩陣計算和圖像融合等關鍵技術。 一、圖像拼接概述 圖像拼接是將多張有重疊區域的圖像合并成一幅全景圖的技術&#xff0c;廣泛應用于全景攝影、衛星圖像處理、醫學影像等領域。其核心技術…

如何通過 5 種方式向 Android 手機添加音樂

想把音樂添加到你的安卓手機&#xff0c;然后隨時隨地無需網絡連接就能欣賞你喜愛的音樂嗎&#xff1f;這不再是麻煩。現在&#xff0c;你可以按照本指南中的有效方法&#xff0c;將音樂添加到你的安卓手機上。讓我們在安卓手機上聆聽我們美妙的歌曲吧。 第 1 部分&#xff1a;…

VS Code 項目中的 .vscode 目錄詳解

VS Code 項目中的 .vscode 目錄詳解 .vscode 目錄是 VS Code 項目的核心配置中心&#xff0c;它包含特定于當前項目的配置&#xff0c;這些配置覆蓋全局設置&#xff0c;確保團隊成員獲得一致的開發環境體驗。 .vscode 目錄中的核心文件 文件名作用是否應納入版本控制settin…

Ubuntu22.04安裝opengauss并配置遠程訪問、JDBC連接

內容概括 最近在研究怎么在ubuntu服務器環境下使用opengauss&#xff0c;看了下官方下載地址沒有適配ubuntu的安裝包。仔細翻了下官方文檔&#xff0c;發現安裝指南里有提供一個deb包安裝方案&#xff0c;有適配ubuntu&#xff0c;經過實踐可行&#xff0c;于是記錄下來給有需要…

國產智能體“雙子星”:實在Agent vs Manus(核心架構與技術實現路徑對比)

2025年&#xff0c;人工智能領域迎來重要轉折點——大模型的光環逐漸消散&#xff0c;落地應用成為行業焦點。 正如業內人士所言&#xff1a;“2023年&#xff0c;大家普遍覺得要買一個大模型&#xff0c;但訓練完了怎么用起來&#xff0c;大家一頭霧水。” 在這一背景下&…

pgAdmin 4 連接 postgreSQL

環境如下&#xff1a; 宿主機為Windows 11postgreSQL安裝在宿主機上的Linux虛機中&#xff0c;Hypervisor是VirtualBoxpgAdmin 4 已安裝在宿主機上 本文講述&#xff1a;如何通過宿主機上的pgAdmin 連接到虛擬機中的PG。 設置監聽 默認的PG監聽主機為localhost&#xff0c;…

HTTP 緩存策略:強緩存與協商緩存的深入解析

在HTTP緩存策略中&#xff0c;強緩存和協商緩存是兩種常用的機制&#xff0c;用于減少數據傳輸和提高網頁加載速度。它們通過在客戶端和服務器之間建立緩存來避免不必要的網絡請求&#xff0c;從而優化性能并提高用戶體驗。本文將詳細介紹這兩種緩存策略的原理、優勢和適用場景…

Node.js 中的 Token 認證機制詳解

文章目錄 Node.js 中的 Token 認證機制詳解1. Token 認證基礎1.1 什么是 Token 認證&#xff1f;1.2 Token 認證流程 2. JWT (JSON Web Token) 實現2.1 安裝依賴2.2 生成 Token2.3 驗證 Token 中間件 3. 完整實現示例3.1 登錄接口3.2 受保護的路由 4. Token 安全最佳實踐5. Tok…

23 - HaLoAttention模塊

論文《Scaling Local Self-Attention for Parameter Efficient Visual Backbones》 1、作用 HaloNet通過引入Haloing機制和高效的注意力實現&#xff0c;在圖像識別任務中達到了最先進的準確性。這些模型通過局部自注意力機制&#xff0c;有效地捕獲像素間的全局交互&#xf…

2025Mybatis最新教程(五)

第5章 ORM映射 5.1 MyBatis自動ORM失效 MyBatis只能自動維護庫表”列名“與”屬性名“相同時的對應關系,二者不同時,無法自動ORM。 自動ORM失效建表 create table t_managers(mgr_id int primary key auto_increment,mgr_name varchar(50),mgr_pwd varchar(50) ); 添加數據…

解決lombok注解失效問題

Lombok 注解失效是 Java 開發中的常見問題&#xff0c;通常由依賴配置、IDE 支持或構建工具設置引起。最近在拉取別人springboot3jdk21版本的項目時遇到了lombok注解失效&#xff0c;導致項目無法啟動的問題&#xff0c;以下是我的解決方案&#xff1a; 首先檢查idea 的lombok…