【泛型,数据结构,List接口,Set接口】
泛型,數據結構,List,Set
-
泛型使用
-
數據結構
-
List
-
Set
1 泛型
1.1 泛型的介紹
- 泛型是一種類型參數,專門用來保存類型用的
- 最早接觸泛型是在ArrayList,這個E就是所謂的泛型了。使用ArrayList時,只要給E指定某一個類型,里面所有用到泛型的地方都會被指定對應的類型
1.2 使用泛型的好處
- 不用泛型帶來的問題
- 集合若不指定泛型,默認就是Object。存儲的元素類型自動提升為Object類型。獲取元素時得到的都是Object,若要調用特有方法需要轉型,給我們編程帶來麻煩.
- 使用泛型帶來的好處
- 可以在編譯時就對類型做判斷,避免不必要的類型轉換操作,精簡代碼,也避免了因為類型轉換導致的代碼異常
1.3 泛型的注意事項
-
泛型在代碼運行時,泛型會被擦除。后面學習反射的時候,可以實現在代碼運行的過程中添加其他類型的數據到集合
- 泛型只在編譯時期限定數據的類型 , 在運行時期會被擦除
1.4 自定義泛型類
-
當一個類定義其屬性的時候,不確定具體是什么類型時,就可以使用泛型表示該屬性的類型
-
定義的格式
- 在類型名后面加上一對尖括號,里面定義泛型。一般使用一個英文大寫字母表示,如果有多個泛型使用逗號分隔
- public class 類名<泛型名>{ … }
-
泛型的確定
- 當創建此泛型類是 , 確定泛型類中泛型的具體數據類型
-
練習
1.3 自定義泛型接口
-
當定義接口時,內部方法中其參數類型,返回值類型不確定時,就可以使用泛型替代了。
-
定義泛型接口
- 在接口后面加一對尖括號 , 尖括號中定義泛型 , 一般使用大寫字母表示, 多個泛型用逗號分隔
- public interface<泛型名> { … }
- 舉例 :
-
泛型的確定
- 實現類去指定泛型接口的泛型
- 實現了不去指定泛型接口的泛型 , 進行延續泛型 , 回到泛型類的使用
1.4 自定義泛型方法
-
當定義方法時,方法中參數類型,返回值類型不確定時,就可以使用泛型替代了
-
泛型方法的定義
- 可以在方法的返回值類型前定義泛型
- 格式 : public <泛型名> 返回值類型 方法名(參數列表){ … }
- 舉例 : public void show(T t) { … }
-
泛型的確定
- 當調用一個泛型方法 , 傳入的參數是什么類型, 那么泛型就會被確定
-
練習
package com.itheima.genericity_demo.genericity_method;import java.util.ArrayList; import java.util.Arrays;public class Test {public static void main(String[] args) {// Collection集合中 : public <T> T[] toArray(T[] a) : 把集合中的內容存儲到一個數組中 , 進行返回ArrayList<String> list = new ArrayList<>();list.add("abc");list.add("ads");list.add("qwe");String[] array = list.toArray(new String[list.size()]);System.out.println(Arrays.toString(array));}// 接收一個集合 , 往集合中添加三個待指定類型的元素public static <X> void addElement(ArrayList<X> list, X x1, X x2, X x3) {list.add(x1);list.add(x2);list.add(x3);} }
1.5 通配符
-
當我們對泛型的類型確定不了,而是表達的可以是任意類型,可以使用泛型通配符給定
符號就是一個問號:? 表示任意類型,用來給泛型指定的一種通配值。如下
-
泛型通配符結合集合使用
- 泛型通配符搭配集合使用一般在方法的參數中比較常見。在集合中泛型是不支持多態的,如果為了匹配任意類型,我們就會使用泛型通配符了。
- 方法中的參數是一個集合,集合如果攜帶了通配符,要特別注意如下
- 集合的類型會提升為Object類型
- 方法中的參數是一個集合,集合如果攜帶了通配符,那么此集合不能進行添加和修改操作 , 可以刪除和獲取
1.6 受限泛型
-
受限泛型是指,在使用通配符的過程中 , 對泛型做了約束,給泛型指定類型時,只能是某個類型父類型或者子類型
-
分類 :
- 泛型的下限 :
- <? super 類型> //只能是某一類型,及其父類型,其他類型不支持
- 泛型的上限 :
- <? extends 類型> //只能是某一個類型,及其子類型,其他類型不支持
- 泛型的下限 :
2 數據結構
-
棧結構 : 先進后出
-
隊列結構 : 先進先出
-
數組結構 : 查詢快 , 增刪慢
-
鏈表結構 : 查詢慢 , 增刪快
-
二叉樹
-
二叉樹 : 每個節點最多有兩個子節點
-
二茬查找樹 : 每個節點的左子節點比當前節點小 , 右子節點比當前節點大
-
二茬平衡樹 : 在查找樹的基礎上, 每個節點左右子樹的高度不超過1
-
紅黑樹 :
-
每一個節點或是紅色的,或者是黑色的
-
根節點必須是黑色
-
如果一個節點沒有子節點或者父節點,則該節點相應的指針屬性值為Nil,這些Nil視為葉節點,每個葉節點(Nil)是黑色的
-
不能出現兩個紅色節點相連的情況
-
對每一個節點,從該節點到其所有后代葉節點的簡單路徑上,均包含相同數目的黑色節點
-
添加元素 :
-
-
-
哈希表結構 :
- 哈希值:是JDK根據對象的地址或者字符串或者數字算出來的int類型的數值
- Object類中有一個方法可以獲取對象的哈希值
public int hashCode():返回對象的哈希碼值 - 對象的哈希值特點
- 同一個對象多次調用hashCode()方法返回的哈希值是相同的
- 默認情況下,不同對象的哈希值是不同的。而重寫hashCode()方法,可以實現讓不同對象的哈希值相同
3 List集合
-
List集合是Collection集合子類型,繼承了所有Collection中功能,同時List增加了帶索引的功能
-
特點 :
- 元素的存取是有序的【有序】
- 元素具備索引 【有索引】
- 元素可以重復存儲【可重復】
-
常見的子類
- ArrayList:底層結構就是數組【查詢快,增刪慢】
- Vector:底層結構也是數組(線程安全,同步安全的,低效,用的就少)
- LinkedList:底層是鏈表結構(雙向鏈表)【查詢慢,增刪快】
-
List中常用的方法
List繼承了Collection中所有方法,元素具備索引特性,因此新增了一些含有索引的特有方法
- public void add(int index, E element): 將指定的元素,添加到該集合中的指定位置上。
- public E get(int index):返回集合中指定位置的元素
- public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
- public E set(int index, E element):用指定元素替換集合中指定位置的元素,返回值的更新前的元素
-
LinkedList類
- LinkedList底層結構是雙向鏈表。每個節點有三個部分的數據,一個是保存元素數據,一個是保存前一個節點的地址,一個是保存后一個節點的地址。可以雙向查詢,效率會比單向鏈表高。
- LinkedList特有方法
- public void addFirst(E e):將指定元素插入此列表的開頭。
- public void addLast(E e):將指定元素添加到此列表的結尾。
- public E getFirst():返回此列表的第一個元素。
- public E getLast():返回此列表的最后一個元素。
- public E removeFirst():移除并返回此列表的第一個元素。
- public E removeLast():移除并返回此列表的最后一個元素。
ArrayList集合擴容分析
F:\黑馬\01-JavaSE進階面授\day05【泛型,數據結構,List接口,Set接口】\資料
package com.itheima.list_demo;import java.util.ArrayList; import java.util.Arrays;public class ArrayListDemo {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("于禁");list.add("華佗");list.add("潘鳳");/*ArrayList集合是屬于 -- 數組結構研究集合如何進行擴容 ?空參構造方法 : Object[] elementData = {};*/int[] arr = {};int[] newArr = Arrays.copyOf(arr, 10);System.out.println(Arrays.toString(newArr));} }4 Set集合
- Set集合也是Collection集合的子類型,沒有特有方法。Set比Collection定義更嚴謹
- 特點 :
- 元素不能保證插入和取出順序(無序)
- 元素是沒有索引的(無索引)
- 元素唯一(元素唯一)
- Set常用子類
-
HashSet:底層由HashMap,底層結構哈希表結構。
去重,無索引,無序。
哈希表結構的集合,操作效率會非常高。 -
LinkedHashSet:底層結構鏈表加哈希表結構。
具有哈希表表結構的特點,也具有鏈表的特點。
鏈表結構:是為了保證插入順序
哈希表結構:是為了去重
存儲元素的時候,先過哈希表,如果哈希表能夠接受數據,進一步存到鏈表結構表結構實實現
-
TreeSet:底層是有TreeMap,底層數據結構 紅黑樹。
去重,讓存入的元素具有排序(升序排序)
-
-
HashSet概述 :
- java.util.HashSet是Set接口的實現類,沒有特有方法。 底層是哈希表結構,具有去重特點。
-
哈希值
- 哈希值:是JDK根據對象的地址或者字符串或者數字算出來的int類型的數值
- Object類中有一個方法可以獲取對象的哈希值
- public int hashCode?():返回對象的哈希碼值
- 對象的哈希值特點
- 同一個對象多次調用hashCode()方法返回的哈希值是相同的
- 默認情況下,不同對象的哈希值是不同的。而重寫hashCode()方法,可以實現讓不同對象的哈希值相同
-
哈希表
- JDK8之前,底層采用數組+鏈表實現,可以說是一個元素為鏈表的數組
- JDK8以后,在長度比較長的時候,底層實現了優化
-
LinkedHashSet
4 集合總結
package com.itheima.test; /*集合 :單列集合 : Collection接口List接口 : 1 有序 , 2 有索引 , 3 元素可以重復ArrayList類 : 數組結構(查詢快 , 增刪慢)LinkedList類 : 鏈表結構(查詢滿 , 增刪快)Set 接口 : 1 無序 , 2 無索引 , 3 元素唯一HashSet類 : 哈希表結構(JDK8之前 : 數組 + 鏈表 )(JDK8包含及之后 : 數組 + 鏈表/紅黑樹)LinkedHashSet類 : 元素唯一并有序 . 哈希表 + 鏈表TreeSet類 : 紅黑樹(可以對元素進行排序 , 還可以保證元素唯一) , 今天不學雙列集合 : Map接口TreeMap類 : 紅黑樹(可以對元素進行排序 , 還可以保證元素唯一)HashMap類 : 哈希表結構(JDK8之前 : 數組 + 鏈表 )(JDK8包含及之后 : 數組 + 鏈表/紅黑樹)集合的遍歷 : 單列集合的遍歷1 普通for循環(根據所以獲取元素值)只能遍歷List集合體系2 迭代器所有的單列集合3 增強for所有的單列集合,和數組*/ public class Test {public static void main(String[] args) {} } package com.itheima.test;import java.util.ArrayList; import java.util.Iterator;public class ArrayListDemo {public static void main(String[] args) {// 創建集合對象ArrayList<String> list = new ArrayList<>();// 直接添加元素list.add("馬云祿");list.add("關鳳");list.add("關銀屏");list.add("貂蟬");list.add("孫尚香");// 迭代器Iterator<String> it = list.iterator();while (it.hasNext()) {String s = it.next();System.out.println(s);}System.out.println("===========");// 增強forfor (String s : list) {System.out.println(s);}System.out.println("===========");// 普通for循環for (int i = 0; i < list.size(); i++) {String s = list.get(i);System.out.println(s);}} } package com.itheima.test;import java.util.Iterator; import java.util.LinkedList; /*因為底層為雙向鏈表public void addFirst(E e):將指定元素插入此列表的開頭。public void addLast(E e):將指定元素添加到此列表的結尾。public E getFirst():返回此列表的第一個元素。public E getLast():返回此列表的最后一個元素。public E removeFirst():移除并返回此列表的第一個元素。public E removeLast():移除并返回此列表的最后一個元素。*/ public class LinkedListDemo {public static void main(String[] args) {// 創建集合對象LinkedList<String> list = new LinkedList<>();// 直接添加元素list.add("馬云祿");list.add("關鳳");list.add("關銀屏");list.add("貂蟬");list.add("孫尚香");// 遍歷集合// 迭代器Iterator<String> it = list.iterator();while(it.hasNext()){String s = it.next();System.out.println(s);}System.out.println("============");// 增強forfor (String s : list) {System.out.println(s);}System.out.println("============");// 普通forfor (int i = 0; i < list.size(); i++) {String s = list.get(i);System.out.println(s);}} } package com.itheima.test;import java.util.HashSet; import java.util.Iterator;/*HashSet要想保證元素的唯一 , 那么元素所在的類必須重寫hashCode和equals方法 !!!!!!*/ public class HashSetDemo {public static void main(String[] args) {HashSet<String> hs = new HashSet<>();hs.add("abs");hs.add("abc");hs.add("abs");hs.add("abc");// 遍歷方式// 迭代器Iterator<String> it = hs.iterator();while(it.hasNext()){String s = it.next();System.out.println(s);}System.out.println("===============");// 增強forfor (String h : hs) {System.out.println(h);}} } package com.itheima.test;public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;if (age != student.age) return false;return name != null ? name.equals(student.name) : student.name == null;}@Overridepublic int hashCode() {int result = name != null ? name.hashCode() : 0;result = 31 * result + age;return result;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';} } package com.itheima.test;import java.util.HashSet; import java.util.Iterator;/*HashSet要想保證元素的唯一 , 那么元素所在的類必須重寫hashCode和equals方法 !!!!!!*/ public class HashSetDemo2 {public static void main(String[] args) {// 創建集合對象HashSet<Student> hs = new HashSet<>();// 創建元素對象Student s1 = new Student("張三" , 23);Student s2 = new Student("張三" , 23);Student s3 = new Student("李四" , 24);// 添加到集合中hs.add(s1);hs.add(s2);hs.add(s3);// 迭代器Iterator<Student> it = hs.iterator();while(it.hasNext()){Student s = it.next();System.out.println(s);}System.out.println("===========");// 增強forfor(Student s : hs){System.out.println(s);}} } package com.itheima.test;import java.util.Iterator; import java.util.LinkedHashSet;public class LinkedHashSetDemo {public static void main(String[] args) {LinkedHashSet<Student> linkedHashSet = new LinkedHashSet<>();// 創建元素對象Student s1 = new Student("張三" , 23);Student s2 = new Student("張三" , 23);Student s3 = new Student("李四" , 24);linkedHashSet.add(s1);linkedHashSet.add(s2);linkedHashSet.add(s3);// 迭代器Iterator<Student> it = linkedHashSet.iterator();while(it.hasNext()){Student s = it.next();System.out.println(s);}System.out.println("======================");// 增強forfor (Student s : linkedHashSet) {System.out.println(s);}} }總結
以上是生活随笔為你收集整理的【泛型,数据结构,List接口,Set接口】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络技术——路由器原理与测试
- 下一篇: 服务器系统lede,[OpenWrt W