泛型
泛型機制
基本概念:
- 通常情況下集合中可以存放不同類型的對象,是因爲將所有對象都看做Object類型放入的,因此
從集合中取出元素時也是Object類型,爲了表達該元素真實的數據類型,則需要強制類型轉換,
而強制類型轉換可能會引發類型轉換異常。
- 爲了避免上述錯誤的發生,從Java5開始增加泛型機制,也就是在集合名稱的右側使用<數據類型>
的方式來明確要求該集合中可以存放的元素類型,若放入其它類型的元素則編譯報錯。
- 泛型只在編譯時期有效,在運行時期不區分是什麼類型。
底層原理:
1.泛型的本質就是參數化類型,也就是讓數據類型作爲參數傳遞,其中E相當於形式參數負責佔位,
而使用集合時<>中的數據類型相當於實際參數,用於給形式參數E進行初始化,從而使得集合中所
有的E被實際參數替換,由於實際參數可以傳遞各種各樣廣泛的數據類型,因此得名爲泛型。
2.如:
//其中i叫做形式參數,負責佔位 其中E叫做形式參數,負責佔位
//int i = 10; E = String;
//int i = 20; E = Integer;
public static void show(int i) { public interface List {
... ...
} }
//其中10叫做實際參數,負責給形式參數初始化 //其中String叫做實際參數
show(10); List lt1 = ...;
show(20); List lt2 = ...;
泛型的本質就是將數據類型作爲參數傳遞
自定義泛型接口:
泛型接口和普通接口的區別就是後面添加了類型參數列表,可以有多個類型參數,如:<E, T, .. >
等
自定義泛型方法類:
- 泛型類和普通類的區別就是類名後面添加了類型參數列表,可以有多個類型參數,如:<E, T, .. >
等。
- 實例化泛型類時應該指定具體的數據類型,並且是引用數據類型而不是基本數據類型。
- 父類有泛型,子類可以選擇保留泛型也可以選擇指定泛型類型。
- 子類必須是“富二代”,子類除了指定或保留父類的泛型,還可以增加自己的泛型。
自定義泛型方法:
- 泛型方法就是我們輸入參數的時候,輸入的是泛型參數,而不是具體的參數。我們在調用這個泛型
方法的時需要對泛型參數進行實例化。
- 泛型方法的格式:
[訪問權限] <泛型> 返回值類型 方法名([泛型標識 參數名稱]) { 方法體; }
- 在靜態方法中使用泛型參數的時候,需要我們把靜態方法定義爲泛型方法。
泛型被繼承的處理方式:
泛型在繼承上的體現:
如果B是A的一個子類或子接口,而G是具有泛型聲明的類或接口,則G並不是G的子類型!
比如:String是Object的子類,但是List並不是List的子類。
通配符的使用
- 有時候我們希望傳入的類型在一個指定的範圍內,此時就可以使用泛型通配符了。
- 如:之前傳入的類型要求爲Integer類型,但是後來業務需要Integer的父類Number類也可以傳
入。
- 泛型中有三種通配符形式:
<?> 無限制通配符:表示我們可以傳入任意類型的參數。 /不支持添加,獲取類型是Object
<? extends E> 表示類型的上界是E,只能是E或者是E的子類。 /不支持添加,獲取類型是E
<? super E> 表示類型的下界是E,只能是E或者是E的父類。/添加類型不能超過E,獲取類型是Object
Set集合(熟悉)
基本概念:
- java.util.Set集合是Collection集合的子集合,與List集合平級。
- 該集合中元素沒有先後放入次序,且不允許重複。
- 該集合的主要實現類是:HashSet類 和 TreeSet類以及LinkedHashSet類。
- 其中HashSet類的底層是採用哈希表進行數據管理的。
- 其中TreeSet類的底層是採用紅黑樹進行數據管理的。
- 其中LinkedHashSet類與HashSet類的不同之處在於內部維護了一個雙向鏈表,鏈表中記錄了元
素的迭代順序,也就是元素插入集合中的先後順序,因此便於迭代。
哈希表:(元素爲單項鍊表的數組)
紅黑樹:
常用方法:
參考Collection集合中的方法即可!
hashset底層是hashMap
元素放入HashSet集合的原理:
- 使用元素調用hashCode方法獲取對應的哈希碼值,再由某種哈希算法計算出該元素在數組中的索
引位置。
- 若該位置沒有元素,則將該元素直接放入即可。
- 若該位置有元素,則使用新元素與已有元素依次比較哈希值,若哈希值不相同,則將該元素直接放
入。
- 若新元素與已有元素的哈希值相同,則使用新元素調用equals方法與已有元素依次比較。
- 若相等則添加元素失敗,否則將元素直接放入即可。
- 思考:爲什麼要求重寫equals方法後要重寫hashCode方法呢?
解析:當兩個元素調用equals方法相等時證明這兩個元素相同,重寫hashCode方法後保證這兩個元
素得到的哈希碼值相同,由同一個哈希算法生成的索引位置相同,此時只需要與該索引位置已有元
素比較即可,從而提高效率並避免重複元素的出現。
TreeSet集合
基本概念:
- 二叉樹主要指每個節點最多隻有兩個子節點的樹形結構。
- 滿足以下3個特徵的二叉樹叫做有序二叉樹。
a.左子樹中的任意節點元素都小於根節點元素值;
b.右子樹中的任意節點元素都大於根節點元素值;
c.左子樹和右子樹的內部也遵守上述規則;
- 由於TreeSet集合的底層採用紅黑樹(特殊的有序二叉樹)進行數據的管理,當有新元素插入到TreeSet集合時,需要使
用新元素與集合中已有的元素依次比較來確定新元素的合理位置。
- 比較元素大小的規則有兩種方式:
使用元素的自然排序規則進行比較並排序,讓元素類型實現java.lang.Comparable接口;
使用比較器規則進行比較並排序,構造TreeSet集合時傳入java.util.Comparator接口;
- 自然排序的規則比較單一,而比較器的規則比較多元化,而且比較器優先於自然排序;
由於TreeSet集合底層是採用紅黑樹,所以元素有大小次序,默認從小到大打印
//從JAVA8開始支持Lambda表達式:(表達式)->{方法體}
Comparator<Student> comparator=(Student o1,Student o2)->{return o1.getAge()-o2.getAge()}
Map集合
基本概念:
- java.util.Map<K,V>集合中存取元素的基本單位是:單對元素,其中類型參數如下:
K - 此映射所維護的鍵(Key)的類型,相當於目錄。
V - 映射值(Value)的類型,相當於內容。
- 該集合中key是不允許重複的,而且一個key只能對應一個value。
- 該集合的主要實現類有:HashMap類、TreeMap類、LinkedHashMap類、Hashtable類、
Properties類。
- 其中HashMap類的底層是採用哈希表進行數據管理的。
- 其中TreeMap類的底層是採用紅黑樹進行數據管理的。
- 其中LinkedHashMap類與HashMap類的不同之處在於內部維護了一個雙向鏈表,鏈表中記錄了
元素的迭代順序,也就是元素插入集合中的先後順序,因此便於迭代。
- 其中Hashtable類是古老的Map實現類,與HashMap類相比屬於線程安全的類,且不允許null作
爲key或者value的數值。
- 其中Properties類是Hashtable類的子類,該對象用於處理屬性文件,key和value都是String類
型的。
- Map集合是面向查詢優化的數據結構, 在大數據量情況下有着優良的查詢性能。
- 經常用於根據key檢索value的業務場景。
常用方法:
元素放入HashMap集合的原理:
- 使用元素的key調用hashCode方法獲取對應的哈希碼值,再由某種哈希算法計算在數組中的索引
位置。
- 若該位置沒有元素,則將該鍵值對直接放入即可。
- 若該位置有元素,則使用key與已有元素依次比較哈希值,若哈希值不相同,則將該元素直接放
入。
- 若key與已有元素的哈希值相同,則使用key調用equals方法與已有元素依次比較。
- 若相等則將對應的value修改,否則將鍵值對直接放入即可。
相關常量:
- DEFAULT_INITIAL_CAPACITY : HashMap的默認容量是16。
- DEFAULT_LOAD_FACTOR:HashMap的默認加載因子是0.75。
- threshold:擴容的臨界值,該數值爲:容量*填充因子,也就是12。
- TREEIFY_THRESHOLD:若Bucket中鏈表長度大於該默認值則轉化爲紅黑樹存儲,該數值是8。
- MIN_TREEIFY_CAPACITY:桶中的Node被樹化時最小的hash表容量,該數值是64。
Map集合中的三種遍歷方式:
Collections類
基本概念:
java.util.Collections類主要提供了對集合操作或者返回集合的靜態方法
常用方法: