Java語法進階11-泛型

泛型

泛型:參數化的類型,即把數據類型當做參數來傳遞

有的地方又稱爲泛化的類型,用一個單個大寫字母,例如<T>來代表任意類型,這個T就是泛化的類型。

泛型的好處:

(1)表示某個變量的類型更靈活

(2)安全:有了泛型,在編譯期間就可以避免不符合類型的數據賦值

(3)避免數據類型轉換

泛型類或泛型接口

【修飾符】 class 類名<類型變量列表/泛型類型形參列表>{

}
【修飾符】 interface 接口名<類型變量列表/泛型類型形參列表>{

}

使用

(1)創建對象時

在創建類的對象時指定類型變量對應的實際類型參數,指定泛型實參時,必須左右兩邊一致,不存在多態現象

(2)繼承、實現接口

在繼承泛型類或實現泛型接口時,指定類型變量對應的實際類型參數

注意

(1)<類型變量列表/泛型類型形參列表>:使用單個的大寫字母表示,例如:<T>,<E>,<R>...

(2)<類型變量列表/泛型類型形參列表>:可以多個,每個之間使用,分割,例如:<K,V>

(3)如果要指定<類型變量列表/泛型類型形參列表>的實際類型,必須是引用數據類型,不能是基本數據類型

(4)類和接口上的類型形參不能用於靜態方法中

(5)<類型變量列表/泛型類型形參列表>可能有上限,< T extends 上限1 > 

類型變量的上限

當在聲明類型變量時,如果不希望這個類型變量代表任意引用數據類型,而是某個系列的引用數據類型,那麼可以設定類型變量的上限。

< T extends 上限1 & 上限2 ...>

上限中類只能有一個,如果有必須在最左邊,接口的話可以多個。多個上限之間是&(與)的關係。

如果在聲明<類型變量>時沒有指定任何上限,默認上限是java.lang.Object。

泛型擦除

當使用參數化類型的類或接口時,如果沒有指定泛型,會發生泛型擦除,泛型的類型就會自動按照最左邊的第一個上限處理。如果沒有指定上限,上限即爲Object。

泛型方法

如果我們定義類、接口時沒有使用<類型變量>,但是某個方法定義時或靜態方法定義時,想要自己定義<類型變量>就可定義泛型方法

語法:

【修飾符】 <類型變量列表/泛型類型形參列表> 返回值類型  方法名(【數據形參列表】)【throws 異常列表】

使用:

方法被調用時,根據方法的實參的類型自動推斷。

注意:

泛型方法的定語與泛型類的定義注意點相同,並且泛型方法可定義靜態方法

每一個泛型方法的<類型變量列表/泛型類型形參列表>是獨立的,和別的方法無關,和類上面的泛型也無關

類型通配符

當我們聲明一個方法時,某個形參的類型是一個參數化的泛型類或泛型接口類型(Map<K,V>),但是在聲明方法時,又不確定該泛型實際類型,我們可以考慮使用類型通配符。

形式:

(1)泛型類/接口名<?>        ?代表任意引用數據類型

(2)泛型類/接口名<? extends 上限>  ?代表的是該上限或上限的子類類型

(3)泛型類/接口名<? super 下限>     ?代表的是該下限或下限的父類類型

注意:

<?>:不可變,因爲<?>類型不確定,編譯時,任意類型都是錯

<? extends 上限>:不可變,因爲<? extends 上限>的?可能是上限或上限的子類,即類型不確定,編譯按任意類型處理都是錯。

<? super 下限>:可以將值修改爲下限或下限子類的對象,因爲<? super 下限>?代表是下限或下限的父類,那麼設置爲下限或下限子類的對象是安全的。

泛型的其他小問題

1、<>在左右兩邊 類型必須一致

2、JDK1.7之後允許右邊<>裏面空着,根據左邊的自動推斷

3、try...catch的catch裏面不能使用T這種來代表任意異常類型。

4、泛型類不能創建數組對象

5、泛型可用於可變形參列表(T... t)

 超類通配符<? super 下限>主要用於靈活的寫入和比較,而<? extends 上限>主要用於讀寫,不能寫入或者修改

數組算法昇華

1、數組的反轉

方法一:

1、藉助一個新數組

2、首尾對應位置交換

缺點:需要藉助一個數組,浪費額外空間,原數組需要垃圾回收

方法二:

數組對稱位置的元素互換。

2、數組的擴容

(1)先創建一個新數組,可以擴容爲原來的1.5倍、2倍等

(2)把舊數組的數據賦值到新數組中

(3)把新元素添加到newArr的最後

(4)如果下面繼續使用arr,可以讓arr指向新數組

數組擴容太多會造成浪費,太少會導致頻繁擴容,效率低下

3、數組元素的插入

(1)判斷數組是否需要擴容

  如果需要,先擴容

(2)把[index]位置和它後面的元素往右移動

(3)在[index]位置放入新元素

4、數組元素的刪除

(1)把[index+1]位置和它後面的元素往左移動

(2)把當前數組的最後一個元素還原(0/null)

5、數組的二分查找

二分查找:對摺對摺再對摺

要求:要求數組元素必須支持比較大小,並且數組中的元素已經按大小排好序

6、數組的直接選擇排序

int[] arr = {....};

//輪數 = arr.length-1
for(int i=0; i<arr.length-1; i++){
  //(1)找出本輪最小值
  int minIndex = i;
  for(int j=i+1; j<arr.length-1; j++){
    if(arr[minIndex] > arr[j]){
      minIndex = j;
    }
  }
  //(2)如果本輪最小值不在它應該在的位置
  if(minIndex != i){
    int temp = arr[minIndex];
    arr[minIndex] = arr[i];
    arr[i] = temp;
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章