Java基礎(二十)——泛型萬用字元和資料結構
泛型的萬用字元
當使用泛型類或者泛型介面,傳遞的資料中,泛型的型別不確定,可以通過萬用字元<?>表示。一旦程式當中使用泛型的萬用字元後,只能使用Object類中的共性的方法,集合中元素自身方法無法使用
萬用字元的基本使用
泛型的萬用字元:不指定使用什麼型別來接收的時候,此時可以使用?,?表示未知的萬用字元。
此時只能接收資料,不能往該集合中儲存資料
程式碼示例:
1 public static void main(String[] args) { 2 //可以儲存整數的集合 3 Collection<Integer> list01 = newArrayList<Integer>(); 4 //此時list01可以儲存整數的資料 5 //展示list01集合當中的資料 6 getElement(list01); 7 //可以儲存String字串的集合 8 Collection<String> list01 = new ArrayList<String>(); 9 //此時list02可以儲存字串的資料 10 11 } 12 public static void getElement(Collection<?>oll){ 13 //只能接受Integer型別的資料14 //此時?可以接收 15 }
備註:泛型不存在繼承關係Collection<Object>list = new ArrayList<String>();這是一種錯誤寫法。
萬用字元的高階用法——受限泛型
之前設定泛型的時候,實際上是可以任意設定的。只要是類就可以的,但是在Java的泛型當中還可以指定一個泛型的上限和下限。
泛型的上限
- 格式:型別名稱<? extends 類名>物件名稱
- 意義:只能接收該類型別及其子類型別
泛型的下限
- 格式:型別名稱<? super 類名> 物件名
- 意義:只能接收該類型別及其父類型別
比如說:已知的頂級父類Object,String類,Number類,Integer類,其中Number類是Integer類的父類。
例項程式碼:
1 public static void main(String[] args){ 2 //初始化三個集合 3 Collection<Integer> list01 = new ArrayList<Integer>(); 4 Collection<String> list02 = new ArrayList<>(); 5 Collection<Number> list03 = new ArrayList<>(); 6 Collection<Double> list04 = new ArrayList<>(); 7 } 8 9 //定義方法 此時可以接收任意的資料型別 10 public static void getElement(Collection<?> coll){ 11 //...... 12 } 13 //定義方法只讓該方法接收數字型別 Number型別或者Number的子類 14 public static void getElement01(Collection<?extends Number> coll){ 15 //..... 16 } 17 //定義方法只讓該方法接收數字型別及其以上的型別 18 public static void getElement01(Collection<?super Number> coll){ 19 //..... 20 }
資料結構
程式 = 資料結構 + 演算法
資料儲存的常用結構:棧、佇列、陣列、連結串列和紅黑樹
棧:stack,又稱堆疊,它是運算受限的線性表結構,它的限制是僅允許在標的的一端進行插入和刪除操作,不允許在其他任何位置進行新增、查詢、刪除等任何操作。
簡單地說,採用該結構的集合,對元素的存取有以下特點:
- 先進後出(存進去的元素,要在它後面的元素依次取出後,才能取出該元素).例如:子彈壓進彈夾。
- 棧的入口、出口都是棧的頂端位置
壓棧:就是儲存元素,把元素儲存到棧的頂端位置,棧中已有的元素依次向棧底方向移動一個位置。
彈棧:就是取出元素,把棧的頂端位置元素取出,棧中已有的元素,依次向棧頂方向移動一個元素。
佇列
佇列:queue,簡稱隊,它同堆疊幾乎是一樣的,也是一種運算受限的線性表結構,它的限制是僅允許在標的的一端進行插入,而在標的的另一端進行刪除。簡單地說,採用結構的集合集合,對元素的存取有以下特點:
先進先出(存進去的元素,要在它前面的元素依次取出後,才能取出該元素)。例如火車過隧道,火車頭先進隧道,火車頭先從隧道出來,車尾後進來,最後出來。
陣列
陣列:Array,是有序的元素序列,陣列在記憶體當中開屁一端連續的空間,並在此空間記憶體儲元素。例如:生活中的酒店,酒店當中的酒店,酒店當中的房間是連續,不間斷,有50個房間,從001—050每個房間都有固定編號,通過變化就可以快速找到酒店房間的住戶
簡單地說,採用此結構的集合,對元素存取有以下特點:
-
查詢元素快:通過索引可以快速的訪問到指定位置的元素。
-
增刪元素慢:
1.指定索引位置增加元素:需要建立一個新陣列,將指定的新元素儲存到指定的索引位置,再把原陣列元素根據它原來的索引,複製到新陣列對應的索引位置。
2.指定索引位置刪除元素:需要建立一個新陣列,把原陣列當中的元素根據索引,複製到新陣列對應索引的位置,原陣列中指定的索引位置元素不復制到新陣列當中。原理圖如下:
原理圖如下:
連結串列結構
-
-
單向連結串列:連結串列當中只有一條連結串列,不能保證元素的順序(儲存元素的順序和取出元素順序可能不一致)
-
雙向連結串列:連結串列當中有兩條連結串列,有一條連結串列是專門記錄元素的順序,是有序的集合
連結串列結構特點:
簡單地說,採用此結構的集合,對元素的存取有以下特點:
-
多個節點之間,通過地址進行連線。比如:多個人玩丟手絹,每個人右手拉住下一個人的左手,上一個人的右手拉住該人的左手。以此類推,多個人就被連線起來。
-
查詢元素比較慢:想要查詢某個元素,需要查詢某個元素,需要通過連線的節點,一次向後查詢指定的元素。
-
刪除元素比較快:
1.增加一個元素:只需要修改連線下個元素的地址即可。
2.刪除一個元素:只需要修改連線下一個元素的地址即可。
紅黑樹
-
簡單的理解,就是類似於我們生活中的樹的結構,只不過每個節點上都最多隻能有2個子節點
頂上的節點稱為根節點,兩邊的被稱為“左子樹”和“右子樹”
在二叉樹中有一種比較特殊的樹結構叫做紅黑樹,紅黑樹本身就是一個二叉樹。
紅黑樹的約束:
1.節點可以是紅色的或者黑色的。
2.根節點必須是黑色的。
3.葉子結點(空節點)是黑色的。
4.每個紅色的節點的子節點都是黑色的。
5.任何一個節點到其每一個葉子節點的所有路徑上的黑色節點數是相同的。
紅黑樹的特點:查詢的速度非常快,趨近於平衡樹,查詢葉子節點最小次數和最大次數不能超過2倍。
List集合
主要介紹java.util.List
集合和java.util.Set
集合
List介面介紹
java.util.List
介面繼承自Collection介面,是單列集合的一個重要分支,在List集合當中允許出現重複的元素,所有的元素都是以一種線性方式進行儲存的,在List集合當中,基本上可以通過索引來訪問集合當中的元素,另外List集合還有一個特點就是元素是有序的,指的是存取元素順序相同。
List介面當中的常用API方法:增刪改查
除了繼承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):在指定索引位置上替換成給定的元素,並且返回更新前的元素。
程式碼示例:
List集合的子類
ArrayList集合
有索引,有序,元素可重複,長度可變的陣列,可以儲存null元素,增刪慢,查詢快
LinkedList集合
java.util.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():刪除尾結點的元素
- public E pop():從此列表所表示的堆疊處當中彈出一個元素。
- public void push(E e):將元素推入到此列表所表示的堆疊當中。
- public boolean isEmpty():如果此列表不包含任何元素,則返回true。