泛型
泛型:參數化的類型,即把數據類型當做參數來傳遞
有的地方又稱爲泛化的類型,用一個單個大寫字母,例如<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)先創建一個新數組,可以擴容爲原來的1.5倍、2倍等
(2)把舊數組的數據賦值到新數組中
(3)把新元素添加到newArr的最後
(4)如果下面繼續使用arr,可以讓arr指向新數組
數組擴容太多會造成浪費,太少會導致頻繁擴容,效率低下
(1)判斷數組是否需要擴容
如果需要,先擴容
(2)把[index]位置和它後面的元素往右移動
(3)在[index]位置放入新元素
(1)把[index+1]位置和它後面的元素往左移動
二分查找:對摺對摺再對摺
要求:要求數組元素必須支持比較大小,並且數組中的元素已經按大小排好序
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;
}
}