高清圖解28個高并發之數據結構/數據結構場景匹配技巧分析
Java 集合以 ArrayList、LinkedList、HashSet、TreeSet 和 HashMap 等組件為核心,構筑了強大而靈活的數據結構體系。這些組件精心設計以滿足不同的性能和功能需求,如 ArrayList 的動態數組支持快速隨機訪問,而 LinkedList 的雙向鏈表結構則擅長于頻繁的插入和刪除操作。HashSet 基于哈希表提供高效的元素查找,TreeSet 則通過紅黑樹維持元素排序。對于多線程環境,CopyOnWriteArraySet 和 ConcurrentHashMap 等并發集合保證了線程安全,同時優化了讀寫性能。這些設計精妙的組件,不僅提升了數據處理的效率,也簡化了復雜問題的解決方案,了解他的設計就掌握了他的原理,本篇注重設計。
1、JDK集合數據結構范圍
1.1. 列表(List)
圖片
- ArrayList: 基于動態數組實現,支持快速隨機訪問。
- LinkedList: 基于雙向鏈表實現,適合頻繁的插入和刪除操作。
- CopyOnWriteArrayList: 線程安全的變體,寫操作時復制數組。
1.2. 集合(Set)
圖片
- HashSet: 基于 HashMap 實現,保證元素唯一性。
- LinkedHashSet: 哈希表和鏈表實現,維護元素插入順序。
- TreeSet: 基于紅黑樹,元素處于排序狀態。
- CopyOnWriteArraySet: 線程安全的變體,寫操作時復制數組。
1.3. 隊列(Queue)
圖片
- LinkedListQueue (作為隊列使用時): 支持先進先出(FIFO)。
- ArrayDeque: 雙端隊列,支持快速插入和刪除。
- PriorityQueue: 支持優先級排序的隊列。
- ConcurrentLinkedQueue: 線程安全的無界隊列。
- BlockingQueue: 支持阻塞操作的隊列接口,具體實現包括:
ArrayBlockingQueue: 有界阻塞隊列。
LinkedBlockingQueue: 基于鏈表結構的阻塞隊列。
PriorityBlockingQueue: 具有優先級的阻塞隊列。
SynchronousQueue: 不存儲元素的阻塞隊列,主要用于任務竊取。
圖片
1.4. 雙端隊列(Deque)
圖片
- ArrayDeque: 基于動態數組,實現雙向隊列。
- LinkedList (作為雙端隊列使用時): 基于鏈表,實現雙向隊列。
1.5. 映射(Map)
圖片
- HashMap: 基于哈希表,存儲鍵值對。
- LinkedHashMap: 哈希表加鏈表,維護插入順序。
- TreeMap: 基于紅黑樹,鍵處于排序狀態。
- Hashtable: 古老的 Map 實現,線程安全。
- ConcurrentHashMap: 線程安全的 HashMap 實現。
- ConcurrentSkipListMap: 線程安全的 TreeMap 實現。
- IdentityHashMap: 使用 == 比較鍵的身份,而不是使用 equals() 方法。
- WeakHashMap: 鍵是弱引用,適合緩存使用。
1.6. 其他
圖片
- Vector: 古老的動態數組實現,線程安全。
- Stack: 古老的棧實現,可以使用 Vector 或 Deque 實現。
- Properties: 用于處理配置文件的集合類。
2、集合數據結構設計與分析
2.1 ArrayList
ArrayList 是 Java 集合框架中的一個非常核心的類,實現了 List 接口。以下是 ArrayList 的設計:
設計思考:
- 需求場景:
在許多編程任務中,需要一個能夠動態增長和收縮的數組。例如,在實現數據集合、緩沖區管理、實現其他數據結構(如棧、隊列)等場景中,動態數組是非常有用的。
- 現有技術局限性:
傳統的數組類型在 Java 中是固定長度的,一旦創建,其大小不能改變,這限制了其在需要動態大小管理時的使用。
技術融合:
ArrayList 融合了動態數組的概念,提供了一個能夠根據需要自動調整大小的數組。
設計理念:
ArrayList 提供了一個能夠根據添加元素的數量動態增長的數組,同時保持了隨機訪問的能力,使其在執行索引位置的查找時非常高效。
實現方式:
ArrayList 內部使用一個可變大小的數組(默認為空,隨著元素添加自動擴容)來存儲元素,當數組容量不足以容納更多元素時,會自動創建一個更大的新數組,并將舊數組中的元素復制到新數組中。
2.1.1 數據結構
圖片
圖說明:
- ArrayList:
Java 集合框架中的一個類,實現了 List 接口。
- Object[] elementData:
ArrayList 內部使用一個動態數組來存儲元素,這個數組的類型是 Object[],可以存儲任何類型的對象。
當數組容量不足以存儲更多元素時, ArrayList 會自動進行擴容,通常是將數組大小增加到原來的1.5倍。
int size:
表示 ArrayList 中實際存儲的元素數量。
size 與 elementData 數組的 length 屬性不同, length 表示數組的總容量,而 size 表示當前存儲的元素個數。
2.1.2 執行流程
圖片
圖說明:
- 初始化 ArrayList:
創建一個空的 ArrayList 或指定初始容量的 ArrayList。
- 檢查容量:
在添加元素前,檢查當前數組容量是否足夠。
添加元素:
嘗試將新元素添加到 ArrayList。
容量不足:
如果當前容量不足以容納新元素,進入擴容流程。
擴容:
創建一個新的數組,容量通常是原數組的1.5倍。
復制舊數組到新數組:
將舊數組中的所有元素復制到新數組中。
增加新元素:
在新數組中插入新元素。
獲取元素:
根據索引獲取元素。
索引檢查:
檢查索引是否在有效范圍內。
返回元素:
返回指定索引處的元素。
刪除元素:
刪除 ArrayList 中的指定元素。
移除指定索引元素:
將指定索引處的元素移除。
數組元素向前移動:
將移除元素之后的元素向前移動一位,填補空位。
2.2 LinkedList
LinkedList 在 Java 中是基于雙向鏈表實現的,它包含多個節點,每個節點都包含數據和兩個引用,分別指向前一個節點和后一個節點。以下是 LinkedList 的設計:
設計思考:
- 需求場景:
在許多編程任務中,需要一個可以快速進行插入和刪除操作的動態數組。例如,在實現棧、隊列、雙向隊列等數據結構時,這些操作非常常見。
- 現有技術局限性:
ArrayList 提供了快速的隨機訪問能力,但在進行插入和刪除操作時,可能需要移動數組中的大量元素,導致效率低下。
Vector 類似于 ArrayList,但它是線程安全的,但使用 synchronized 進行同步,導致并發性能較差。
技術融合:
LinkedList 結合了鏈表的插入和刪除效率高的特點,并提供了雙向鏈表的實現,允許從兩端快速地添加或移除元素。
設計理念:
LinkedList 通過使用鏈表結構,可以有效地進行插入和刪除操作,因為這些操作僅需要改變節點的指針,而不需要移動整個數組。
它還實現了 List 接口,提供了與 ArrayList 相同的接口,但具有不同的性能特性。
實現方式:
LinkedList 由一系列 Node 對象組成,每個 Node 包含數據和兩個引用( previous 和 next),分別指向前一個和后一個節點。
2.2.1 數據結構
以下是 LinkedList 數據結構的主要特點:
- 鏈式存儲:元素在內存中不是連續存儲的,而是通過指針(引用)連接起來的。
- 節點結構:每個節點至少包含兩部分信息,一個是存儲數據的元素,另一個是指向同鏈表中下一個節點的引用。在雙向鏈表中,還會有一個指向前一個節點的引用。
- 動態大小: LinkedList 的大小是動態的,可以根據需要隨時插入或刪除節點。
- 允許空鏈表:可以創建一個不包含任何節點的空鏈表。
- 插入和刪除效率高:在鏈表的任意位置插入或刪除節點的操作時間復雜度為 O(1),因為這些操作只涉及到節點的引用的改動。
- 訪問元素效率低:訪問特定索引位置的元素需要從頭節點開始遍歷鏈表,時間復雜度為 O(n)。
- 沒有空間浪費:與數組不同,鏈表不需要預先分配固定大小的存儲空間。
- 有序性:鏈表中的節點按照它們被插入的順序保持有序。
- 可以實現為雙向或循環鏈表:標準的 LinkedList 實現可以是雙向的,也可以是循環的(尾節點指向頭節點)。
2.2.1 執行流程
圖片
圖說明:
- 初始化 LinkedList:
創建一個空的 LinkedList 實例。
- 添加元素:
將新元素添加到 LinkedList。
刪除元素:
從 LinkedList 刪除指定的元素。
訪問元素:
根據索引訪問 LinkedList 中的元素。
遍歷 LinkedList:
通過節點間的鏈接順序遍歷整個 LinkedList。
檢查邊界條件:
在執行索引相關操作前,檢查索引是否在有效范圍內。
獲取節點:
獲取指定索引處的節點。
更新節點指針:
在添加或刪除元素時,更新節點間的指針。
返回節點數據:
返回指定節點的數據。
LinkedList 節點:
LinkedList 由一系列節點組成,每個節點包含前一個節點、后一個節點和節點數據。
Node prev:
節點中保存的對前一個節點的引用。
Node next:
節點中保存的對后一個節點的引用。
Node data:
節點中保存的數據。
2.3 CopyOnWriteArrayList
CopyOnWriteArrayList 在 Java 中是一個線程安全的變體數組列表,其特點是在修改(寫操作)時通過復制整個底層數組來實現,以此保證讀操作的線程安全和高性能。以下是 CopyOnWriteArrayList 的設計:
設計思考:
- 需求場景:
在多線程環境中,讀操作遠比寫操作頻繁,且對數據的實時性要求不是非常高的場景。例如,緩存系統、實時數據的訂閱發布模型等。
- 現有技術局限性:
傳統的線程安全實現,如 Vector 或通過 synchronized 同步代碼塊或方法,可能會因為寫操作導致的線程阻塞,嚴重影響并發性能。
技術融合:
CopyOnWriteArrayList 采用了寫時復制(Copy-On-Write)的策略,當進行寫操作(添加、刪除等)時,先復制整個數組,然后在新數組上進行操作,而讀操作則直接作用于原數組,從而提高了讀操作的性能。
設計理念:
利用了讀操作遠多于寫操作的特性,通過分離讀和寫操作,使得讀操作無需加鎖,從而提高了并發讀的性能。
實現方式:
內部使用一個數組來存儲元素,所有寫操作都會創建一個新的數組,并將修改應用于新數組,然后原子性地將內部數組引用指向新數組。
2.3.1 數據結構
圖片
圖說明:
- CopyOnWriteArrayList:
表示 CopyOnWriteArrayList 的實例。
- Object[] array:
CopyOnWriteArrayList 內部使用的一個數組 array 來存儲元素。這是原始數組,所有讀操作都訪問這個數組。
Object[] newArray:
寫操作時創建的新數組。當寫操作發生時,這個數組是原始數組的一個深拷貝。
寫操作:
包括添加、刪除或修改元素。寫操作不是在原始數組上進行,而是在新數組上進行。
工作原理:
- 讀操作:
多個讀線程可以同時訪問和遍歷 array,因為數組是不可變的。
- 寫操作:
當寫操作發生時(如添加、刪除或修改元素),寫線程首先會創建原始 array 的一個副本 newArray。
寫線程在 newArray 上進行添加、刪除或修改操作。
寫操作完成后,寫線程會原子性地將 CopyOnWriteArrayList 的內部數組引用指向 newArray。
數據一致性:
在寫操作進行時,讀線程仍然可以訪問舊的內部數組 array,從而保證了數據的一致性。
2.3.2 執行流程
圖片
圖說明:
- 初始化 CopyOnWriteArrayList:
創建一個空的 CopyOnWriteArrayList 實例。
- 內部數組 array:
CopyOnWriteArrayList 內部使用一個數組來存儲元素。
讀操作:
直接讀取內部數組的元素,是線程安全的,因為內部數組不可變。
寫操作:
包括添加、刪除和修改元素,需要創建內部數組的一個新副本。
復制數組:
在執行寫操作前,復制內部數組,以保證新元素的添加不會影響讀操作。
添加元素:
向 CopyOnWriteArrayList 添加新元素。
刪除元素:
從 CopyOnWriteArrayList 刪除元素。
修改元素:
修改 CopyOnWriteArrayList 中的元素。
數組拷貝:
創建內部數組的一個新副本,并在新副本上執行寫操作。
2.4 HashSet
HashSet 是 Java 集合框架中的一個基本成員,它是 java.util 包下的一個非常常用的集合類。以下是 HashSet 的設計:
設計思考:
- 需求場景:
在很多應用場景中,需要存儲不重復的元素,并且需要快速地添加、刪除和查找元素。
例如,在處理配置選項、用戶權限、郵件地址列表等場景時,確保元素的唯一性是非常重要的。
- 現有技術局限性:
ArrayList 和 LinkedList 雖然可以存儲元素,但它們需要線性時間來查找元素,且不保證元素的唯一性。
技術融合:
HashSet 基于 HashMap 實現,它結合了哈希表的快速查找特性來提供常數時間復雜度的添加、刪除和查找操作,同時保證了元素的唯一性。
設計理念:
HashSet 提供了一個不允許重復元素的數據結構,它使用哈希表的鍵來存儲元素,而不關心值。
這種設計使得 HashSet 在保證元素唯一性的同時,提供了高效的操作性能。
實現方式:
HashSet 的每個元素都作為 HashMap 的一個鍵存儲,而對應的值是一個固定的對象(通常是一個名為 PRESENT 的私有靜態對象)。
2.4.1 數據結構
圖片
圖說明:
- HashSet:
表示 HashSet 類的實例,用于存儲不重復的元素。
- HashMap:
HashSet 的內部實現基于 HashMap。
數組 (Buckets) :
HashMap 使用一個數組來存儲桶(Buckets),桶是用于存儲 Entry 對象的容器。
索引1, 索引2, 索引3:
表示數組中的具體索引位置,每個索引對應一個桶。
Entry (鏈表/紅黑樹) :
每個桶可以包含多個 Entry 對象,它們通過鏈表或紅黑樹形式連接。
鏈表 Entry:
在哈希沖突較少的情況下, Entry 對象通過鏈表連接。
紅黑樹 Entry:
當鏈表長度超過閾值時,鏈表可能會被轉換成紅黑樹以提高搜索效率。
2.4.2 執行流程
圖片
圖說明:
- 創建 HashSet 實例:
初始化 HashSet 對象。
- 添加元素:
將元素添加到 HashSet。
計算元素的hashCode:
調用元素的 hashCode() 方法計算其哈希碼。
確定數組索引位置:
根據哈希碼和數組長度確定數組索引位置。
處理哈希沖突:
如果索引位置已有元素,處理哈希沖突。
元素添加至鏈表/紅黑樹:
將新元素添加至對應索引的鏈表或紅黑樹中。
刪除元素:
從 HashSet 刪除元素。
計算元素的hashCode:
調用元素的 hashCode() 方法計算其哈希碼。
確定數組索引位置:
根據哈希碼和數組長度確定數組索引位置。
找到對應的哈希桶:
定位到數組中對應的哈希桶。
從鏈表/紅黑樹中刪除元素:
從對應索引的鏈表或紅黑樹中刪除元素。
遍歷 HashSet:
遍歷 HashSet 中的所有元素。
獲取數組:
獲取 HashSet 內部的數組。
遍歷每個桶:
遍歷數組的每個桶。
遍歷鏈表/紅黑樹:
遍歷桶內的鏈表或紅黑樹中的所有元素。
2.5 LinkedHashSet
LinkedHashSet 是 Java 集合框架中的一個成員,它結合了 HashSet 的快速查找特性和 LinkedList 的插入順序保持功能。以下是 LinkedHashSet 的設計:
設計思考:
- 需求場景:
在很多應用場景中,需要快速地插入、刪除和查找元素,同時也需要保持元素的插入順序。
例如,在處理用戶會話、緩存實現、任務調度等場景時,保持元素的添加順序是非常重要的。
- 現有技術局限性:
HashSet 提供了常數時間的添加、刪除和查找性能,但它不保持元素的插入順序。
TreeSet 保持了元素的排序順序,但不是插入順序,且它的性能不如 HashSet。
ArrayList 和 LinkedList 保持了插入順序,但它們的查找性能為線性時間復雜度。
技術融合:
為了結合 HashSet 的快速查找能力和 LinkedList 的插入順序保持能力, LinkedHashSet 應運而生。
設計理念:
LinkedHashSet 底層使用 HashMap 來存儲元素,保證了快速的查找性能。
同時,它在每個 HashMap 的條目上使用一個雙向鏈表來維護元素的插入順序。
實現方式:
LinkedHashSet 繼承自 HashSet,但重寫了 add、 iterator 等方法,以維護插入順序。
它在內部維護了與 HashMap 條目關聯的雙向鏈表的節點,這些節點鏈接了具有相同哈希值但插入順序不同的元素。
2.5.1 數據結構
圖片
圖說明:
- LinkedHashSet:
表示 LinkedHashSet 類的實例,它繼承自 HashSet 并維護元素的插入順序。
- HashMap:
LinkedHashSet 的實現基于 HashMap,用來存儲集合中的元素。
數組 (Buckets) :
HashMap 使用一個數組來存儲桶(Buckets),桶是用于存儲 Entry 對象的容器。
哈希桶:
每個桶內部使用鏈表來解決哈希沖突。
鏈表 Entry:
每個桶包含多個 Entry 對象,它們通過鏈表連接。
紅黑樹 Entry:
當鏈表長度超過閾值時,鏈表可能會被轉換成紅黑樹以提高搜索效率。
鏈表 節點1 和 鏈表 節點2:
表示鏈表中的節點,每個節點存儲著集合中的一個元素,并指向前一個和后一個節點,形成雙向鏈表。
元素:
存儲在 LinkedHashSet 中的最終數據。
2.5.2 執行流程
圖片
圖說明:
- 創建 LinkedHashSet 實例:
初始化 LinkedHashSet 對象。
- 添加元素:
將元素添加到 LinkedHashSet。
計算元素的hashCode:
調用元素的 hashCode() 方法計算其哈希碼。
確定數組索引位置:
根據哈希碼和數組長度確定數組索引位置。
找到對應的哈希桶:
定位到數組中對應的哈希桶。
檢查哈希桶中的鏈表/紅黑樹:
檢查哈希桶中是否已有鏈表或紅黑樹結構。
處理哈希沖突:
如果桶中已有元素,處理哈希沖突。
元素添加至鏈表/紅黑樹:
將新元素添加至對應索引的鏈表或紅黑樹中。
刪除元素:
從 LinkedHashSet 刪除元素。
重新計算元素的hashCode:
調用元素的 hashCode() 方法計算其哈希碼。
確定刪除元素的數組索引位置:
根據哈希碼和數組長度確定數組索引位置。
找到刪除元素的哈希桶:
定位到數組中對應的哈希桶。
從鏈表/紅黑樹中刪除元素:
從對應索引的鏈表或紅黑樹中刪除元素。
遍歷 LinkedHashSet:
遍歷 LinkedHashSet 中的所有元素。
獲取數組:
獲取 LinkedHashSet 內部的數組。
遍歷每個桶:
遍歷數組的每個桶。
遍歷鏈表/紅黑樹:
遍歷桶內的鏈表或紅黑樹中的所有元素。
讀取元素:
讀取鏈表或紅黑樹中的元素。
2.6 TreeSet
TreeSet 是 Java 集合框架中的一個有序集合類,實現了 Set 接口。以下是 TreeSet 的設計:
設計思考:
- 需求場景:
在許多編程任務中,需要存儲不重復的元素,并且這些元素需要保持一定的順序,例如,自然排序或自定義排序順序。
例如,在處理需要排序的配置選項、用戶權限、需要按順序處理的任務列表等場景時,元素的排序順序是非常重要的。
- 現有技術局限性:
HashSet 提供了非常快的查找、添加和刪除操作,但它不保證元素的任何特定順序。
ArrayList 和 LinkedList 可以保持插入順序,但查找操作需要線性時間。
技術融合:
TreeSet 結合了 HashSet 的快速查找特性和 ArrayList/ LinkedList 的元素順序保持功能,但通過使用紅黑樹(一種自平衡的二叉搜索樹)實現,提供了有序的元素集合。
設計理念:
TreeSet 提供了一個不允許重復元素的數據結構,同時保證了元素處于排序狀態,可以進行有效的范圍查詢和排序操作。
實現方式:
TreeSet 內部使用 TreeMap 的實例來存儲元素,其中元素作為鍵,值是一個固定的虛擬對象(如 PRESENT),從而保證了元素的唯一性。
2.6.1 數據結構
圖片
圖說明:
- TreeSet:
表示 TreeSet 類的實例,它實現了 Set 接口,并保證元素處于排序狀態。
- TreeMap:
TreeSet 基于 TreeMap 實現,其中元素作為鍵存儲,而不關心值。
紅黑樹:
TreeMap 的底層數據結構是一個紅黑樹,它是一個自平衡的二叉搜索樹。
根節點:
紅黑樹的根節點,是樹的入口。
左子節點和右子節點:
表示紅黑樹節點的子節點。
元素A, 元素B, 元素C:
實際存儲在 TreeSet 中的數據。
2.6.2 執行流程
圖片
圖說明:
- 添加元素:
計算元素的自然排序:根據元素的自然順序或提供的 Comparator 計算排序。
構建紅黑樹:TreeSet 基于紅黑樹數據結構,確保元素處于排序狀態。
確定插入位置:在紅黑樹中找到元素的插入位置。
插入元素到紅黑樹:將元素插入到紅黑樹中。
- 刪除元素:
計算元素的自然排序:根據元素的自然順序或提供的 Comparator 計算排序。
查找紅黑樹:在紅黑樹中查找要刪除的元素。
刪除元素從紅黑樹:從紅黑樹中刪除元素。
遍歷 TreeSet:
獲取紅黑樹根節點:獲取紅黑樹的根節點,開始遍歷。
遍歷紅黑樹節點:遍歷紅黑樹的每個節點。
讀取元素:從紅黑樹的節點中讀取元素。
2.7 CopyOnWriteArraySet
CopyOnWriteArraySet 是 Java 并發包 java.util.concurrent 中的一個集合類,它是 CopyOnWriteArrayList 的一個變體,用于維護一個線程安全的、動態的元素集合。以下是 CopyOnWriteArraySet 的設計:
設計思考:
- 需求場景:
在多線程環境中,讀操作頻繁而寫操作相對較少的場景,如緩存、實時數據集、事件監聽器集合等。
- 現有技術局限性:
傳統的線程安全集合,如 Collections.synchronizedSet 或 Hashtable,在讀多寫少的場景下可能因為寫操作導致的線程阻塞,影響性能。
技術融合:
CopyOnWriteArraySet 采用了寫時復制(Copy-On-Write)的策略,在讀操作遠多于寫操作的情況下,提高了讀操作的性能。
設計理念:
CopyOnWriteArraySet 利用了讀操作遠多于寫操作的特點,在讀操作時不需要加鎖,從而提高了并發讀的性能。
實現方式:
內部使用 CopyOnWriteArrayList 存儲元素,所有寫操作(添加、刪除等)都會創建一個新的數組副本,然后對新數組進行修改,最后原子性地將內部數組引用指向新數組。
2.7.1 數據結構
圖片
圖說明
- CopyOnWriteArraySet:表示 CopyOnWriteArraySet 類的實例,它提供了線程安全的 Set 集合功能。
- CopyOnWriteArrayList:CopyOnWriteArraySet 基于 CopyOnWriteArrayList 實現,后者是線程安全的 ArrayList 實現。
- 內部數組:CopyOnWriteArrayList 初始的內部數組,用于存儲集合中的元素。
- 內部數組副本:當執行寫操作(如添加、刪除)時,CopyOnWriteArrayList 創建內部數組的一個副本。
- 新內部數組:寫操作完成后,CopyOnWriteArrayList 將內部數組引用指向新的數組副本。
- 元素1、元素2、元素n:表示存儲在 CopyOnWriteArraySet 中的實際數據。
2.7.1 執行流程
圖片
圖說明
- 創建 CopyOnWriteArraySet 實例:初始化 CopyOnWriteArraySet 對象。
- 添加元素:將元素添加到 CopyOnWriteArraySet。
- 復制舊內部數組:為了添加元素,先復制當前的內部數組。
- 修改新內部數組副本:在數組的副本上添加元素。
- 將新內部數組副本設置為當前:將修改后的數組副本設置為當前數組,完成添加操作。
- 刪除元素:從 CopyOnWriteArraySet 刪除元素。
- 復制舊內部數組:為了刪除元素,先復制當前的內部數組。
- 修改新內部數組副本:在數組的副本上刪除元素。
- 將新內部數組副本設置為當前:將修改后的數組副本設置為當前數組,完成刪除操作。
- 遍歷 CopyOnWriteArraySet:遍歷 CopyOnWriteArraySet 中的所有元素。
- 讀取當前內部數組:讀取當前的內部數組,進行遍歷操作。