初識數據結構——Java集合框架解析:List與ArrayList的完美結合

📚 Java集合框架解析:List與ArrayList的完美結合

🌟 前言:為什么我們需要List和ArrayList?

在日常開發中,我們經常需要處理一組數據。想象一下,如果你要管理一個班級的學生名單,或者處理電商網站的商品列表,你會怎么做?Java集合框架中的List和ArrayList就是為解決這類問題而生的利器!

本文將帶你深入探索List接口和ArrayList實現類的奧秘,通過豐富的示例和直觀的圖示,讓你徹底掌握它們的用法和原理。


🧩 第一部分:List接口全景圖

1. 什么是List?

List是Java集合框架中的一個接口,它繼承自Collection接口,代表一個有序的、可重復的元素序列。

public interface List<E> extends Collection<E> {// 一系列方法定義
}
🎯 List的核心特性:
  • 有序性:元素按照插入順序排列
  • 可重復:允許存儲相同的元素
  • 索引訪問:可以通過下標直接訪問元素

2. List的繼承體系(思維導圖)

Iterable
Collection
List
ArrayList
LinkedList
Vector

3. List常用方法速查表

方法簽名功能描述時間復雜度
boolean add(E e)尾部添加元素O(1)
void add(int index, E element)指定位置插入O(n)
E get(int index)獲取指定位置元素O(1)
E set(int index, E element)修改指定位置元素O(1)
E remove(int index)刪除指定位置元素O(n)
int size()返回元素個數O(1)
boolean contains(Object o)判斷是否包含元素O(n)

🚀 第二部分:ArrayList深度剖析

1. ArrayList的底層原理

ArrayList是基于動態數組實現的順序表,它自動處理擴容問題,讓我們可以專注于業務邏輯。

// 底層核心數組
transient Object[] elementData;
// 實際元素數量
private int size;

2. ArrayList的構造方法對比

構造方法說明初始容量
ArrayList()無參構造10
ArrayList(int initialCapacity)指定初始容量自定義
ArrayList(Collection<? extends E> c)從集合構造集合大小

3. 動態擴容機制揭秘(流程圖)

添加元素
容量是否足夠?
直接添加
計算新容量
創建新數組
拷貝數據
添加新元素

擴容規則

  • 首次添加元素時擴容到10
  • 后續按1.5倍增長(int newCapacity = oldCapacity + (oldCapacity >> 1)

4. ArrayList的三種遍歷方式

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));// 1. for循環+下標
for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));
}// 2. 增強for循環
for (String s : list) {System.out.println(s);
}// 3. 迭代器
Iterator<String> it = list.iterator();
while (it.hasNext()) {System.out.println(it.next());
}

實戰應用:撲克牌游戲

🃏1. 撲克牌游戲:買牌、洗牌、發牌完整實現

// 定義一個Card類來表示一張撲克牌
public class Card {// 定義一個整數類型的變量rank,用于表示牌的面值public int rank; // 定義一個字符串類型的變量suit,用于表示牌的花色public String suit; // 重寫toString方法,用于將Card對象以特定格式輸出@Overridepublic String toString() {// 格式化輸出牌的花色和面值return String.format("[%s %d]", suit, rank); }
}// 導入List接口,用于存儲和操作元素列表
import java.util.List; 
// 導入ArrayList類,用于創建動態數組
import java.util.ArrayList; 
// 導入Random類,用于生成隨機數
import java.util.Random; // 定義一個CardDemo類,用于演示撲克牌的操作
public class CardDemo {// 定義一個字符串數組SUITS,包含四種花色public static final String[] SUITS = {"?", "?", "?", "?"}; // 定義一個靜態方法buyDeck,用于創建一副完整的撲克牌private static List<Card> buyDeck() {// 創建一個容量為52的ArrayList對象,用于存儲撲克牌List<Card> deck = new ArrayList<>(52); // 外層循環遍歷四種花色for (int i = 0; i < 4; i++) { // 內層循環遍歷1到13的牌面值for (int j = 1; j <= 13; j++) { // 獲取當前花色String suit = SUITS[i]; // 獲取當前牌面值int rank = j; // 創建一個Card對象Card card = new Card(); // 設置Card對象的牌面值card.rank = rank; // 設置Card對象的花色card.suit = suit; // 將Card對象添加到deck列表中deck.add(card); }}// 返回包含所有撲克牌的列表return deck; }// 定義一個靜態方法swap,用于交換列表中兩個位置的元素private static void swap(List<Card> deck, int i, int j) {// 獲取索引i位置的Card對象Card t = deck.get(i); // 將索引j位置的Card對象賦值給索引i位置deck.set(i, deck.get(j)); // 將臨時變量t(原索引i位置的Card對象)賦值給索引j位置deck.set(j, t); }// 定義一個靜態方法shuffle,用于洗牌private static void shuffle(List<Card> deck) {// 創建一個Random對象,使用固定的種子值,保證每次運行結果一致Random random = new Random(20190905); // 從列表的最后一個元素開始向前遍歷for (int i = deck.size() - 1; i > 0; i--) { // 生成一個0到i之間的隨機整數int r = random.nextInt(i); // 調用swap方法交換索引i和r位置的元素swap(deck, i, r); }}// 程序的入口點public static void main(String[] args) {// 調用buyDeck方法創建一副撲克牌List<Card> deck = buyDeck(); // 打印提示信息,表示剛買回來的牌System.out.println("剛買回來的牌:"); // 打印剛買回來的撲克牌列表System.out.println(deck); // 調用shuffle方法對撲克牌進行洗牌shuffle(deck); // 打印提示信息,表示洗過的牌System.out.println("洗過的牌:"); // 打印洗過的撲克牌列表System.out.println(deck); // 創建一個二維列表hands,用于存儲三個玩家的手牌List<List<Card>> hands = new ArrayList<>(); // 為每個玩家創建一個空的手牌列表,并添加到hands中hands.add(new ArrayList<>()); hands.add(new ArrayList<>()); hands.add(new ArrayList<>()); // 模擬每個玩家輪流抓5張牌的過程for (int i = 0; i < 5; i++) { // 遍歷三個玩家for (int j = 0; j < 3; j++) { // 從deck列表中移除第一張牌,并添加到當前玩家的手牌列表中hands.get(j).add(deck.remove(0)); }}// 打印提示信息,表示剩余的牌System.out.println("剩余的牌:"); // 打印剩余的撲克牌列表System.out.println(deck); // 打印提示信息,表示A玩家手中的牌System.out.println("A手中的牌:"); // 打印A玩家的手牌列表System.out.println(hands.get(0)); // 打印提示信息,表示B玩家手中的牌System.out.println("B手中的牌:"); // 打印B玩家的手牌列表System.out.println(hands.get(1)); // 打印提示信息,表示C玩家手中的牌System.out.println("C手中的牌:"); // 打印C玩家的手牌列表System.out.println(hands.get(2)); }
}

🔺2. 楊輝三角生成器(leetcode118)

在這里插入圖片描述

public List<List<Integer>> generate(int numRows) {List<List<Integer>> triangle = new ArrayList<>();for (int i = 0; i < numRows; i++) {List<Integer> row = new ArrayList<>();for (int j = 0; j <= i; j++) {if (j == 0 || j == i) {row.add(1);} else {row.add(triangle.get(i-1).get(j-1) + triangle.get(i-1).get(j));}}triangle.add(row);}return triangle;}

💡 性能優化與思考

ArrayList的優缺點分析

? 優點

  • 隨機訪問速度快(O(1))
  • 內存連續,緩存友好
  • 尾部操作高效

? 缺點

  • 中間插入/刪除效率低(O(n))
  • 擴容有性能開銷
  • 可能造成內存浪費

替代方案考慮

場景推薦結構原因
頻繁隨機訪問ArrayListO(1)訪問
頻繁插入刪除LinkedListO(1)插入刪除
多線程環境CopyOnWriteArrayList線程安全
固定大小Arrays.asList()不可變

📌 總結與面試必備

  1. List vs ArrayList:List是接口,ArrayList是實現
  2. 擴容機制:初始10,1.5倍增長
  3. 時間復雜度
    • 訪問:O(1)
    • 搜索:O(n)
    • 插入/刪除:平均O(n)
  4. 線程安全:ArrayList非線程安全,多線程需同步
45% 30% 15% 10% ArrayList使用場景 隨機訪問 尾部操作 中間操作 其他

🎁 彩蛋:ArrayList的趣味事實

你知道嗎?ArrayList在JDK1.2中引入,它的設計受到了C++ STL中vector的啟發。但在Java中,為了避免與數學向量概念混淆,才命名為ArrayList!


希望這篇深度解析能幫助你徹底掌握List和ArrayList!如果有任何問題,歡迎在評論區留言討論。別忘了點贊收藏哦~ 💖

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

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

相關文章

ReFormX:現代化的 React 表單解決方案 - 深度解析與最佳實踐

ReFormX文檔 表單開發一直是前端工作中最繁瑣卻又最常見的任務之一。從簡單的登錄表單到復雜的多步驟配置頁面&#xff0c;開發者往往需要編寫大量重復代碼&#xff0c;處理繁瑣的狀態管理、數據驗證和聯動邏輯。ReFormX 應運而生&#xff0c;它不僅是一個表單組件庫&#xff…

WinForm真入門(9)——RichTextBox控件詳解

WinForm中RichTextBox控件詳解&#xff1a;從基礎到高級應用 上一文中筆者重點介紹了TextBox控件的詳細用法&#xff0c;忘記的 請點擊WinForm真入門(8)——TextBox控件詳解&#xff0c;那么本文中的RichTextBox與TextBox有什么區別嗎&#xff0c;光看名字的話&#xff0c;多了…

Draw.io 全面解析與競品分析:圖表繪制工具的深度對比

目錄 一、Draw.io 全面介紹 1. 產品概述 2. 核心功能特點 3. 用戶體驗 4. 商業模式 二、市場競品分析 1. 主要競品概覽 2. 深度功能對比 3. 價格策略對比 4. 技術架構對比 三、用戶場景與選擇建議 1. 不同場景下的工具推薦 2. 未來發展趨勢 四、結論 diagrams.net…

kafka分區策略詳解

Kafka 分區策略詳解 Kafka 的分區策略決定了消息在生產者端如何分配到不同分區&#xff0c;以及在消費者端如何動態分配分區以實現負載均衡。以下是 Kafka 核心分區策略及其適用場景的詳細解析&#xff1a; 1、生產者分區策略 生產者負責將消息發送到 Topic 的特定分區&#…

C++ STL 詳解 ——list 的深度解析與實踐指南

在 C 的標準模板庫&#xff08;STL&#xff09;中&#xff0c;list作為一種重要的序列式容器&#xff0c;以其獨特的雙向鏈表結構和豐富的操作功能&#xff0c;在許多編程場景下發揮著關鍵作用。深入理解list的特性與使用方法&#xff0c;能幫助開發者編寫出更高效、靈活的代碼…

GenerationMixin概述

類 類名簡單說明GenerateDecoderOnlyOutput繼承自 ModelOutput&#xff0c;適用于非束搜索方法的解碼器-only模型輸出類。GenerateEncoderDecoderOutput繼承自 ModelOutput&#xff0c;適用于非束搜索方法的編碼器-解碼器模型輸出類。GenerateBeamDecoderOnlyOutput繼承自 Mod…

【備賽】藍橋杯嵌入式實現led閃爍

原理 由于藍橋杯的板子帶有鎖存器&#xff0c;并且與lcd屏幕有沖突&#xff0c;所以這個就成了考點。 主要就是用定時器來實現&#xff0c;同時也要兼顧lcd的沖突。 一、處理LCD函數 首先來解決與lcd屏幕沖突的問題&#xff0c;把我們所有用到的lcd函數改裝一下。 以下是基…

C++ 并發性能優化實戰:提升多線程應用的效率與穩定性

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;獲得2024年博客之星榮譽證書&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開發技術&#xff0c…

Python----計算機視覺處理(Opencv:道路檢測之車道線擬合)

完整版&#xff1a; Python----計算機視覺處理&#xff08;Opencv:道路檢測完整版&#xff1a;透視變換&#xff0c;提取車道線&#xff0c;車道線擬合&#xff0c;車道線顯示&#xff09; 一、獲取左右車道線的原始位置 導入模塊 import cv2 import numpy as np from matplot…

優選算法的妙思之流:分治——歸并專題

專欄&#xff1a;算法的魔法世界 個人主頁&#xff1a;手握風云 目錄 一、歸并排序 二、例題講解 2.1. 排序數組 2.2. 交易逆序對的總數 2.3. 計算右側小于當前元素的個數 2.4. 翻轉對 一、歸并排序 歸并排序也是采用了分治的思想&#xff0c;將數組劃分為多個長度為1的子…

C語言查漏補缺:基礎篇

1.原理 C語言是一門編譯型計算機語言&#xff0c;要編寫C代碼&#xff0c;C源代碼文本文件本身無法直接執行&#xff0c;必須通過編譯器翻譯和鏈接器的鏈接&#xff0c;生成二進制的可執行文件&#xff0c;然后才能執行。這里的二進制的可執行文件就是我們最終要形成的可執行程…

TPS入門DAY02 服務器篇

1.創建空白插件 2.導入在線子系統以及在線steam子系統庫 MultiplayerSessions.uplugin MultiplayerSessions.Build.cs 3.創建游戲實例以及初始化會話創建流程 創建會話需要的函數&#xff0c;委托&#xff0c;委托綁定的回調&#xff0c;在線子系統接口綁定某一個委托的控制其…

產品經理課程

原型工具 一、土耳其機器人 這個說法來源于 1770 年出現的一個騙局&#xff0c;一個叫沃爾夫岡馮肯佩倫&#xff08;Wolfgang von Kempelen&#xff09;的人為了取悅奧地利女皇瑪麗婭特蕾莎&#xff08;Maria Theresia&#xff09;&#xff0c;“制造”了一個會下國際象棋的機…

nginx中的limit_req 和 limit_conn

在 Nginx 中&#xff0c;limit_req 和 limit_conn 是兩個用于限制客戶端請求的指令&#xff0c;它們分別用于限制請求速率和并發連接數。 limit_req limit_req 用于限制請求速率&#xff0c;防止客戶端發送過多請求影響服務器性能。它通過 limit_req_zone 指令定義一個共享內存…

基于winform的串口調試助手

目錄 一、串口助手界面設計 1.1 串口配置 1.2 接收配置 1.3 發送配置 1.4 接收窗口和發送窗口 1.5 狀態顯示窗口 1.6 串口通訊控件 二、程序編寫 2.1 端口號自動識別并顯示在端口號下拉框 功能說明&#xff1a; 2.2 波特率下拉框顯示 2.3 數據位下拉框顯示 2.4 校…

Docker基礎2

如需轉載&#xff0c;標記出處 本次我們將下載一個 Docker 鏡像&#xff0c;從鏡像中啟動容器 上一章&#xff0c;安裝 Docker 時&#xff0c;獲得兩個主要組件&#xff1a; Docker 客戶端 Docker 守護進程&#xff08;有時稱為“服務器”或“引擎”&#xff09; 守護進程實…

Rocketmq2

一、生產者端防丟失 1. 發送方式選擇 同步發送&#xff1a;使用 send() 方法&#xff0c;等待 Broker 確認響應&#xff08;SendResult&#xff09;&#xff0c;確保消息已成功發送。異步發送&#xff1a;使用 sendAsync() 方法并設置回調函數&#xff0c;處理發送成功 / 失敗…

RabbitMQ詳解,RabbitMQ是什么?架構是怎樣的?

目錄 一,RabbitMQ是什么? 二,RabbitMQ架構 2.1 首先我們來看下RabbitMQ里面的心概念Queue是什么? 2.2 交換器Exchange 2.3 RabbitMQ是什么? 2.4 重點看下優先級隊列是什么? 三,RabbitMQ集群 3.1 普通集群模式 3.2 鏡像隊列集群 一,RabbitMQ是什么? 假設我們程序…

【一步步開發AI運動APP】六、運動計時計數能調用

之前我們為您分享了【一步步開發AI運動小程序】開發系列博文&#xff0c;通過該系列博文&#xff0c;很多開發者開發出了很多精美的AI健身、線上運動賽事、AI學生體測、美體、康復鍛煉等應用場景的AI運動小程序&#xff1b;為了幫助開發者繼續深耕AI運動領域市場&#xff0c;今…

MySQL——DQL的多表查詢

一、交叉連接 標準語法&#xff1a;select * from 表1 cross join 表2 where 表1.公共列 表2.公共列; 簡單語法&#xff1a;select * from 表1 , 表2 where 表1.公共列 表2.公共列; 公共列&#xff1a;兩張表具有相同含義的列&#xff0c;不是列名一樣。 …