【數據結構】 ArrayList簡介與實戰

文章目錄

  • 什么是ArrayList
    • ArrayList相關說明
  • ArrayList使用
    • ArrayList的構造
      • 無參構造
      • 指定順序表初始容量
      • 利用其他 Collection 構建 ArrayList
      • ArrayList常見操作
        • 獲取list有效元素個數
        • 獲取和設置index位置上的元素
        • 在list的index位置插入指定元素
        • 刪除指定元素
        • 刪除list中index位置上的元素
        • 檢測list中是否包含指定元素
        • 查找指定元素第一次出現的位置
        • 截取部分 list
    • ArrayList的遍歷
      • for循環+下標
      • foreach
      • 使用迭代器
      • 注意事項
    • ArrayList的擴容機制
      • 小結
  • ArrayList的具體使用
    • 楊輝三角
      • 題目描述
      • 題目解釋:
      • 解法思路:
      • 代碼實現:
    • 簡單的洗牌算法
      • Card類
      • 買牌(初始化)
      • 洗牌
      • 摸牌
      • 效果展示:
      • 完整代碼:
  • 總結

什么是ArrayList

在集合框架中,ArrayList是一個普通的類,實現了List接口,具體框架圖如下
在這里插入圖片描述

ArrayList相關說明

  1. ArrayList是以泛型方式實現的,使用時必須要先實例化

  2. ArrayList實現了RandomAccess接口,表明ArrayList支持隨機訪問

  3. ArrayList實現了Cloneable接口,表明ArrayList是可以clone的

  4. ArrayList實現了Serializable接口,表明ArrayList是支持序列化的

  5. 和Vector不同,ArrayList不是線程安全的,在單線程下可以使用,在多線程中可以選擇Vector或者CopyOnWriteArrayList

  6. ArrayList底層是一段連續的空間,并且可以動態擴容,是一個動態類型的順序表

ArrayList使用

ArrayList的構造

ArrayList的構造有三種
在這里插入圖片描述

無參構造

ArrayList創建,推薦寫法

// 構造一個空的列表
List<Integer> list1 = new ArrayList<>();

指定順序表初始容量

// 構造一個具有10個容量的列表
List<Integer> list2 = new ArrayList<>(10);
list2.add(1);
list2.add(2);
list2.add(3);

利用其他 Collection 構建 ArrayList

// list3構造好之后,與list2中的元素一致
ArrayList<Integer> list3 = new ArrayList<>(list2);

ArrayList常見操作

ArrayList雖然提供的方法比較多,但是常用方法如下所示
在這里插入圖片描述
例如我們有以下代碼

List<String> list = new ArrayList<>();
list.add("JavaSE");
list.add("JavaWeb");
list.add("JavaEE");
list.add("遇事問春風乄");
list.add("數據結構");

獲取list有效元素個數

// 獲取list中有效元素個數
System.out.println(list.size());

獲取和設置index位置上的元素

注意:index必須介于[0, size)間

System.out.println(list.get(1));//獲取
list.set(1, "JavaWEB");//設置

在list的index位置插入指定元素

在list的index位置插入指定元素后,index及后續的元素統一往后搬移一個位置

list.add(1, "Java數據結構");

刪除指定元素

刪除指定元素,找到了就刪除,該元素之后的元素統一往前搬移一個位置

list.remove("JavaEE")

刪除list中index位置上的元素

注意:index不要超過list中有效元素個數,否則會拋出下標越界異常

list.remove(list.size()-1)

檢測list中是否包含指定元素

包含返回true,否則返回false

if(list.contains("遇事問春風乄")){list.add("遇事問春風乄");
}

查找指定元素第一次出現的位置

indexOf從前往后找,lastIndexOf從后往前找

//從前往后
System.out.println(list.indexOf("JavaSE"));
//從后往前
System.out.println(list.lastIndexOf("JavaSE"));

截取部分 list

使用list中[0, 4)之間的元素構成一個新的SubList返回,但是和ArrayList共用一個elementData數組

List<String> ret = list.subList(0, 4);

ArrayList的遍歷

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

for循環+下標

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) + " ");
}

foreach

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
// 借助foreach遍歷
for (Integer integer : list) {System.out.print(integer + " ");
}

使用迭代器

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
Iterator<Integer> it = list.listIterator();
while(it.hasNext()){System.out.print(it.next() + " ");
}

注意事項

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

ArrayList的擴容機制

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

以下是ArrayList源碼中擴容方式

 Object[] elementData; // 存放元素的空間private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默認空間private static final int DEFAULT_CAPACITY = 10; // 默認容量大小public boolean add(E e) {ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true;}private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;}private void ensureExplicitCapacity(int minCapacity) {modCount++;
// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);}private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;private void grow(int minCapacity) {
// 獲取舊空間大小int oldCapacity = elementData.length;
// 預計按照1.5倍方式擴容int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果用戶需要擴容大小 超過 原空間1.5倍,按照用戶所需大小擴容if (newCapacity - minCapacity < 0)newCapacity = minCapacity;
// 如果需要擴容大小超過MAX_ARRAY_SIZE,重新計算容量大小if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);
// 調用copyOf擴容elementData = Arrays.copyOf(elementData, newCapacity);}private static int hugeCapacity(int minCapacity) {
// 如果minCapacity小于0,拋出OutOfMemoryError異常if (minCapacity < 0)throw new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;}

小結

  1. 檢測是否真正需要擴容,如果是調用grow準備擴容

  2. 預估需要庫容的大小
    初步預估按照1.5倍大小擴容
    如果用戶所需大小超過預估1.5倍大小,則按照用戶所需大小擴容
    真正擴容之前檢測是否能擴容成功,防止太大導致擴容失敗

  3. 使用copyOf進行擴容

ArrayList的具體使用

楊輝三角

題目描述

給定一個非負整數 numRows,生成「楊輝三角」的前 numRows 行。
在這里插入圖片描述

在這里插入圖片描述

題目解釋:

題中返回值為 List<List< Integer > >,意思為返回一個List,這個List里面的每一個元素也為List

解法思路:

List里面放List可以類似與我們的二維數組,而我們的楊輝三角也可以看成一個二維數組

比如我們現在有一個List實例為ret,ret里面存放的是List類型的元素;ret的每一個List元素里存放的是楊輝三角每一行的所有元素
在這里插入圖片描述
通過觀察我們發現,楊輝三角的第一位總是1,并且每一行的最后一個與第一個都為1;其余的等于上面一行的兩個數相加
在這里插入圖片描述

代碼實現:

class Solution {public List<List<Integer>> generate(int numRows) {List<List<Integer>> ret = new ArrayList<>();List<Integer> row = new ArrayList<>();ret.add(row);row.add(1);for(int i = 1;i < numRows;i++) {List<Integer> row1 = ret.get(i-1);List<Integer> row2 = new ArrayList<>(i);ret.add(row2);row2.add(1);for(int j = 1;j < i;j++){int h = row1.get(j) + row1.get(j-1);row2.add(h);}row2.add(1);}return ret;}
}

簡單的洗牌算法

在這里插入圖片描述
比如我們現在需要實現一個簡單的炸金花

Card類

那么我們首先第一步,我們得了解一下撲克,我們除開大小王,就剩下52張牌。每張牌都有相應的面額和花色
在這里插入圖片描述
那么我們便可以建立一個Card類用于描述我們的撲克

class Card {public int rank; // 牌面值public String suit; // 花色@Overridepublic String toString() {return String.format("[%s %d]", suit, rank);}
}

買牌(初始化)

接下來我們需要買一副牌,其實也就是對我們的牌進行初始化

一共四個花色,每一種花色對應13張牌

public static final String[] SUITS = {"?", "?", "?", "?"};// 買一副牌private static List<Card> buyDeck() {List<Card> deck = new ArrayList<>(52);for (int i = 0; i < 4; i++) {for (int j = 1; j <= 13; j++) {String suit = SUITS[i];int rank = j;Card card = new Card();card.rank = rank;card.suit = suit;deck.add(card);}}return deck;}

洗牌

買回來的牌肯定不能直接完,所以我們要進行洗牌

在洗牌環節我們會對一張張牌進行遍歷,然后讓該牌于隨機的一張牌進行交換

這里為了隨機數產生方便,我們選擇從后往前遍歷

private static void swap(List<Card> deck, int i, int j) {Card t = deck.get(i);deck.set(i, deck.get(j));deck.set(j, t);}private static void shuffle(List<Card> deck) {Random random = new Random();//隨機數for (int i = deck.size() - 1; i > 0; i--) {int r = random.nextInt(i);swap(deck, i, r);}}

摸牌

三個人輪流摸牌,我悶這里采用二維數組的思想來實現,也就是List里面的元素是List

摸一張牌,排隊里就少一張牌,這里操作起來非常簡單,我們只需要將牌堆deck的0下標進行刪除就好

使用E remove(int index)刪除當前下標的元素,并返回該元素,將該元素添加到每一位玩家的手中

List<List<Card>> hands = new ArrayList<>();hands.add(new ArrayList<>());hands.add(new ArrayList<>());hands.add(new ArrayList<>());for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {hands.get(j).add(deck.remove(0));}}

效果展示:

在這里插入圖片描述

完整代碼:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;class Card {public int rank; // 牌面值public String suit; // 花色@Overridepublic String toString() {return String.format("[%s %d]", suit, rank);}
}public class CardDemo {public static final String[] SUITS = {"?", "?", "?", "?"};// 買一副牌private static List<Card> buyDeck() {List<Card> deck = new ArrayList<>(52);for (int i = 0; i < 4; i++) {for (int j = 1; j <= 13; j++) {String suit = SUITS[i];int rank = j;Card card = new Card();card.rank = rank;card.suit = suit;deck.add(card);}}return deck;}private static void swap(List<Card> deck, int i, int j) {Card t = deck.get(i);deck.set(i, deck.get(j));deck.set(j, t);}private static void shuffle(List<Card> deck) {Random random = new Random();for (int i = deck.size() - 1; i > 0; i--) {int r = random.nextInt(i);swap(deck, i, r);}}public static void main(String[] args) {List<Card> deck = buyDeck();System.out.println("剛買回來的牌:");System.out.println(deck);shuffle(deck);System.out.println("洗過的牌:");System.out.println(deck);
// 三個人,每個人輪流抓 5 張牌List<List<Card>> hands = new ArrayList<>();hands.add(new ArrayList<>());hands.add(new ArrayList<>());hands.add(new ArrayList<>());for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {hands.get(j).add(deck.remove(0));}}System.out.println("剩余的牌:");System.out.println(deck);System.out.println("A 手中的牌:");System.out.println(hands.get(0));System.out.println("B 手中的牌:");System.out.println(hands.get(1));System.out.println("C 手中的牌:");System.out.println(hands.get(2));}
}

總結

關于《【數據結構】 ArrayList簡介與實戰》就講解到這兒,感謝大家的支持,歡迎各位留言交流以及批評指正,如果文章對您有幫助或者覺得作者寫的還不錯可以點一下關注,點贊,收藏支持一下!

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

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

相關文章

機器學習基礎(二)

線性回歸 誤差是獨立并且具有相同的分布通常認為服從均值為0方差為的高斯分布。 損失函數(loss Function)/代價函數(Cost Function) 其實兩種叫法都可以,損失函數(loss function)或代價函數(cost function)是將隨機事件或其有關隨機變量的取值映射為非負實數以表示該隨…

Android開發之性能優化:過渡繪制解決方案

1. 過渡繪制 屏幕上某一像素點在一幀中被重復繪制多次&#xff0c;就是過渡繪制。 下圖中多個卡片跌在一起&#xff0c;但是只有第一個卡片是完全可見的。背后的卡片只有部分可見。但是Android系統在繪制時會將下層的卡片進行繪制&#xff0c;接著再將上層的卡片進行繪制。但其…

springcloud3 hystrix實現服務降級的案例配置2

一 服務降級的說明 1.1 服務降級說明 "服務器忙&#xff0c;請稍后在試"不讓客戶達等待&#xff0c;立即返回一個友好的提示。 1.2 服務降級的觸發情況 1.程序運行異常&#xff1b; 2.超時&#xff1b; 3.服務熔斷觸發服務降級&#xff1b;4 .線程池/信號量打…

電商增強現實3D模型優化需要關注的4個方面

到目前為止&#xff0c;AR技術已經發展到足以在更廣泛的范圍內實施。 在電子商務中&#xff0c;這項技術有望提供更令人興奮的購物體驗。 為了實現這一目標&#xff0c;在這篇博客中&#xff0c;我將介紹如何針對電子商務中的 AR 優化 3D 模型。 推薦&#xff1a;用 NSDT編輯器…

Python 函數

Built-in Functions — Python 3.11.4 documentation

Transformer(二)(VIT,TNT)(基于視覺CV)

目錄 1.視覺中的Attention 2.VIT框架&#xff08;圖像分類&#xff0c;不需要decoder&#xff09; 2.1整體框架 2.2.CNN和Transformer遇到的問題 2.3.1CNN 2.3.2Transformer 2.3.3二者對比 2.4.公式理解 3TNT 參考文獻 1.視覺中的Attention 對于人類而言看到一幅圖可以立…

區塊鏈系統探索之路:私鑰的壓縮和WIF格式詳解

在前面章節中&#xff0c;我們詳細介紹了公鑰的壓縮&#xff0c;在比特幣網絡中&#xff0c;一個私鑰可以對應兩個地址&#xff0c;一個地址是由未壓縮公鑰所生成的地址&#xff0c;另一個就是由壓縮公鑰所創建的地址&#xff0c;從公鑰到區塊鏈地址的轉換算法&#xff0c;我們…

【設計模式——學習筆記】23種設計模式——解釋器模式Interpreter(原理講解+應用場景介紹+案例介紹+Java代碼實現)

案例引入 通過解釋器模式來實現四則運算&#xff0c;如計算ab-c的值&#xff0c;具體要求 先輸入表達式的形式&#xff0c;比如abc-de&#xff0c;要求表達式的字母不能重復在分別輸入a,b,c,d,e的值最后求出結果 傳統方案 編寫一個方法&#xff0c;接收表達式的形式&#xf…

基于Pan-Tompkins的實時QRS檢測算法:便攜式ANSI-C實現深入解析

引言 隨著醫學工程和移動設備技術的進步&#xff0c;實時QRS檢測算法在心電圖分析中變得越來越重要。其中&#xff0c;Pan-Tompkins算法由于其高效性和準確度&#xff0c;在許多應用中都受到廣泛認可。本文將深入探討此算法的ANSI-C實現&#xff0c;并提供詳細的代碼實例。 1…

【kubernetes】配置資源管理

目錄 Secret 創建 Secret 1、用kubectl create secret命令創建Secret 2、內容用 base64 編碼&#xff0c;創建Secret 使用方式 1、將 Secret 掛載到 Volume 中&#xff0c;以 Volume 的形式掛載到 Pod 的某個目錄下 2、將 Secret 導出到環境變量中 ConfigMap 創建 Co…

請解釋一下CSS中的rem和em單位有什么不同,分別如何使用?

聚沙成塔每天進步一點點 ? 專欄簡介? CSS中的rem和em單位的區別和使用? em單位使用示例&#xff1a; ? rem 單位使用示例&#xff1a; ? 區別和適用場景? 寫在最后 ? 專欄簡介 前端入門之旅&#xff1a;探索Web開發的奇妙世界 記得點擊上方或者右側鏈接訂閱本專欄哦 幾何…

Nginx常見的三個漏洞

目錄 $uri導致的CRLF注入漏洞 兩種常見場景 表示uri的三個變量 案例 目錄穿越漏洞 案例 Http Header被覆蓋的問題 案例 $uri導致的CRLF注入漏洞 兩種常見場景 用戶訪問http://example.com/aabbcc&#xff0c;自動跳轉到https://example.com/aabbcc 用戶訪問http://exa…

[英語單詞] compat; compatibility;compact;entry_SYSENTER_compat

簡介 這個詞compat&#xff0c;馬上就會被簡寫形式所替代。所以一定不要和compact混淆。第一次看到還以為是個新詞來&#xff0c;后來發現是一個縮寫形式。就是兼容的意思&#xff0c;就如同兼容以往的就有事物。 syscall: 32bit: 兼容 entry_SYSENTER_compat 這個是32位程序…

MySQL存儲過程 、存儲函數、以及優缺點

存儲過程 VS 存儲函數&#xff08;函數&#xff09; | | 關鍵字 |調用語法 | 返回值 | 應用場景 | |-存儲過程-|-procedure-|-call 存儲過程()-|-理解為0個或多個-|-一般用于更新-| | 存儲函數 | function | select 函數() | 只能是一個 | 一般用于查詢結構為一個值并返回時| …

三、python Django ORM postgresql[數據定時備份、數據恢復]

一、數據定時備份 解釋&#xff1a;備份指定數據庫&#xff0c;能有效在發生錯誤時&#xff0c;預防錯誤&#xff0c;進行恢復 1.基本備份 #!/bin/bash sudo -u postgres pg_dump -U postgres -d dbname -Fc > /home/postgres/backup/backup.dump # sudo -u postgres&…

訊飛星火、文心一言和通義千問同時編“貪吃蛇”游戲,誰會勝出?

同時向訊飛星火、文心一言和通義千問三個國產AI模型提個相同的問題&#xff1a; “python 寫一個貪吃蛇的游戲代碼” 看哪一家AI寫的程序直接能用&#xff0c;誰就勝出&#xff01; 訊飛星火 訊飛星火給出的代碼&#xff1a; import pygame import sys import random# 初…

Android 13 開啟關閉飛行模式

一.背景 由于客戶定制的Settings里面需要開啟和關閉飛行模式,所以需要實現此功能。 二.前提條件 首先應用肯定要是系統應用,并且導入framework.jar包,具體可以參考: Android 應用自動開啟輔助(無障礙)功能并使用輔助(無障礙)功能_android 自動開啟無障礙服務_龔禮鵬的博客…

步入React正殿 - React組件設計模式

目錄 擴展學習資料 高階組件 /src/components/hoc/withTooltip.js /src/components/hoc/itemA.jsx /src/components/hoc/itemB.jsx /src/App.js 函數作為子組件【Render pprops】 函數作為子組件 /src/components/rp/itemC.jsx【父組件】 /src/components/rp/withToo…

C#調用C++ DLL傳參byte[]數組字節值大于127時會變為0x3f的問題解決

最近做了一個網絡編程的DLL給C#調用&#xff0c;DLL中封裝了一個TCP Client的函數接口&#xff0c;如下所示 //C TCP報文發送接口 int TcpClient_send(unsigned char* buffSend, unsigned int nLen) {unsigned char buff[1024];int len StringToHex(buffSend, buff);int nRet…

stable diffusion安裝包和超火使用文檔,數字人制作網址

一&#xff1a;文生圖、圖生圖 1&#xff1a;stable diffusion&#xff1a;對喜歡二次元、美女小姐姐、大眼萌妹的人及其友好哈哈(o^^o) 1&#xff09;&#xff1a;秋葉大神安裝包和模型包&#xff1a; 鏈接&#xff1a;https://pan.baidu.com/s/11_kguofh76gwhTBPUipepw 提…