十一章:Java 集合
一、集合框架的概述
1、集合:就像一個容器,可以動態的把多個對象的引用放入容器中。簡稱 Java 容器
? 說明:此時的存儲,主要指的是內存層面的存儲,不涉及到持續化的存儲(.txt, .jpg, avi,數據庫中)
2、數組在存儲多個數據方面的特點:
? >一旦初始化之后,長度就確定了
? >一旦定義好,其元素的類型就確定了。我們只能操作指定類型的數據。比如: String[] arr; int[] arr1;
? 數組在存儲多個數據方面的缺點:
? >一旦初始化,其長度就不可修改
? >數組中提供的方法非常有限,對于添加、刪除、插入數據等操作非常不便,效率也不高
? >獲取數據中實際元素個數的需求,數據沒有線程的屬性或方法可用
? >數組存儲數據的特點:有序、可重復。對于無序的、不可重復的需求,無法滿足
二、集合框架:Collection 與 Map
List ---->“動態”數組
Set----->高中講的“集合”
Map---->高中函數: y=f(x) 可以 key 多對一 value 不可以 key 一對多 value
三、Collection 接口中的 方法的使用
像 Collection 接口的實現類中的對象中添加數據 obj 時,要求 obj 所在類要重寫 equals
package com.java.kcw1;import org.junit.Test;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;/**集合元素的遍歷操作,使用 Iterator* @author Jackson_kcw* @Time 2025-03-01 PM1:52*/
public class InteratorTest {@Testpublic void test1() {Collection coll1=new ArrayList();coll1.add("a");coll1.add("b");coll1.add("c");coll1.add(false);Iterator iterator = coll1.iterator();
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());//遍歷操作while(iterator.hasNext()) {//next(): 指針下移;將下移以后集合位置上的元素返回System.out.println(iterator.next());}}
}
集合對象每次調用 iterator()方法都得到一個全新的迭代器對象,默認游標都在集合的第一個元素之前
內部定義了 remove(),可以在遍歷的時候,刪除集合中的元素。此方法不同于直接嗲用 remove
For-each
package com.java.kcw1;import org.junit.Test;import java.util.ArrayList;
import java.util.Collection;/**JDK5.0新增 foreach 循環,用于* @author Jackson_kcw* @Time 2025-03-01 PM2:19*/
public class ForTest {@Testpublic void test() {Collection coll=new ArrayList();coll.add("AA");coll.add("BB");coll.add(11); //自動裝箱System.out.println(coll.size());//for( 集合元素的類型 局部變量:集合對象)for(Object obj:coll){System.out.println(obj);}}
}
List 接口概述:List 集合了類元素有序、可重復
面試題目:ArrayList\LinkedList\Vector 三者的異同
同:三個類都實現了 List 接口,存儲數據的特點相同:元素有序、可重復
異:
ArrayList::作為 List 接口的主要實現類,線程不安全,效率高
LinkedList:對于頻繁的插入和刪除操作,使用效率比 ArrayList 高,底層使用雙向鏈表存儲
Vector:作為 List 接口的古老實現類;線程安全,效率低
List 接口中的常用方法
總結常用方法:
增:add(Object obj)
刪:remove(int index) / remove(Object obj)
改:set(int index,Object ele)
查:get(int index)
插:add(int index,Object ele)
長度:size()
遍歷:一、Iterator 迭代器方式 二、for each 三、普通的循環
Set接口:存儲無序的、不可重復的數據 —>高中講的集合
? HashSet: 作為 Set 接口的主要實現類;線程不安全;可以存儲 null 值
? LinkedHashSet:作為 HashSet 子類;遍歷其內部數據時,可以按照添加的順序遍歷
? TreeSet:可以按照添加對象的指定屬性,進行排序
Set 接口沒有額外一些方法,使用的都是 Collection 里面聲明的方法
Set
以 HashSet 為例:
1、無序性:不等于隨機性。存儲的數據在底層數組中并非按照數據所以你的順序添加,而是根據數據的 hash 值來確定的
2、不可重復性:保證添加的元素按照 equals()方法判斷時,不能返回 true.即相同的元素只能添加一個
二、添加元素的過程:以 HashSet 為例:
? 我們向 HashSet 添加元素 a,首先調用元素a 所在類的 hashCode()方法,計算 a 的哈希值,此哈希值接著通過某種算法計算出在 HashSet 底層數組中的存放完位置(即為:索引位置),判斷數組在此位置是否已經有元素:
? 如果此位置上沒有其他元素,則元素 a 添加成功
? 如果此位置有元素 b,則比較元素 a 與元素 b 的 哈希值:
? 如果 hash 值不同,則元素 a 添加成功
? 如果 hash 值相同,賊需要調用元素 a 所在類的 equals()方法:equals()返回 true,元素 a 添加失敗
? equals()返回 false,則元素 a 添加成功
向 TreeSet 里面添加的數據,要求是相同類的對象,不能添加不同類的對象
五、Map 接口
5-1、|—Map:雙列數據,存儲 key-value 的值 ---------類似高中的函數 :y=f(x)
? |—HashMap:作為 Map 的主要實現類;線程不安全,效率高;可以存儲 null 的 key 和 value
? |----LinkedHashMap:保證在遍歷 map 元素時,可以按照添加的順序實現遍歷
? |—TreeMap:保證按照添加的 key-value 對 進行排序,實現排序遍歷。此時考慮 key 的自然排序或定制排序
? | —Hashtable:作為古老的實現類;線程安全,效率低;不可存儲 null 的 key 和 value
? |—Properties:常用來處理配置文件。key 和 value 都是 String 類型
HashMap 的底層: 數組+鏈表(jdk7 及之前)
? 數組+鏈表+紅黑樹(jdk8)
5-2 Map 結構的理解
5-3 HashMap 的底層實現原理
以 jdk7 為例說明:
HashMap map= new HashMap();
在實例化以后,底層創建了長度為 16 的一維數組 Entry[] table
…可能已經執行過多次 put…
map.put(key1,value1):
首先,調用 key1 所在類的 hashCode()計算 key1 哈希值,此哈希值經過某種算法計算以后,得到在 Entry 數組中的存放位置
如果此位置上的數據為空,此時的 key1-value1 添加成功
如果此位置的數據不為空,(意味著此位置上存在一個或多個數據(以鏈表形式存在)),比較 key1 和已經存在的一個或多個數據的哈希值:
? 如果 key1 的哈希值與已經存在的數據的哈希值都不相同,此時的 key1-value1 添加成功
? 如果 key1 的哈希值和已經存在的某一個數據(key2-value2)的哈希值相同,繼續比較:調用 key1 所在類的 equals()方法,比較:
? 如果 equals()返回 false:此時的 key1-value1 添加成功
? 如果 equals()返回 true: 使用 value1 替換value2
JDK8 相較于 7 在底層實現方面的不同:
1、new HashMap():底層沒有創建一個長度為 16 的數組
2、jdk8 底層的數組是:Node[],而非 Entry[]
3、首次調用 put 方法時,底層創建長度為 16 的數組
4、jdk7 底層結構只有數組加鏈表 jdk8 底層結構:數據+鏈表+紅黑樹
? 當數組的某一個索引位置上的元素以鏈表形式存在的數據個數>8 且當前數組的長度>64,此時索引位置上的所有數據改為使用紅黑樹存儲
?這里面跳過了 hashMap 底層實現原理,這一部分講的比較復雜和抽象,本人因為時間原因跳過了,但是建議再找文檔或視頻看看
5-4 Map接口中常用的方法
工具類 Collections:操作 Collection、Map 的工具類
面試題:Collections 與 Collection 的區別
對比項 | Collection | Collections |
---|---|---|
定義 | Collection 是 java 的接口 | Collections 是 Java 提供的工具類 |
作用 | 定義了 Java 集合的基本操作,如 List、Set等的父接口 | 提供集合操作的工具方法,如排序、搜索、線程安全包裝等 |
子類/實現方式 | List\Set\Queue 等結合框架的接口 | 不能被繼承,只能直接調用其靜態方法 |
常見方法 | add()、remove()、size()等 | sort()、shuffle()、synchronizedList()等 |