應用:
1. 類型安全檢查
2. 編寫通用Java程序
- 類型安全檢查
JDK5 之前集合對象使用問題:
(1)向集合添加任何類型對象。
(2)從集合取出對象時,數據類型丟失,使用與類型相關方法,強制類型轉換。
泛型語法: List<泛型類型> 規定 List集合中元素類型
泛型技術:只是編譯器階段技術,爲javac命令,起到類型安全檢查作用,生成.class文件後,泛型信息將會被擦除。
List— 參數化模型
例:
public void demo1() {
// 應用泛型集合
List<String> list = new ArrayList<String>();// 這個集合只能添加String類型數據
list.add("泛型集合");
list.add("指定數據類型");
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);// 取出數據
System.out.println(s);
}
}
可以利用泛型技術對 Map、Set、List進行類型安全檢查
- List: ArrayList和LinkedList
對List遍歷存在三種方法:
(1)list是有序的可以通過size 和get(index)方法進行遍歷
(2)因爲List繼承collection接口,可以通過Collection 的iterator進行遍歷。
(3)JDK5引入 foreach循環結構
例:
@Test
public void demo2() {
// 使用類型安全list
List<String> list = new LinkedList<String>();
// 使用泛型,只能向list添加 String類型
list.add("aaa");
list.add("bbb");
list.add("ccc");
// 遍歷list 三種方法
// 1. 由於list是有序的 通過 size和get方法進行遍歷
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
System.out.println("----------");
// 2. 由於list繼承collection接口 通過collection的iterator方法 進行遍歷
Iterator<String> iterator = list.iterator();
// 遍歷iterator 通過迭代器hasNext 和next方法進行遍歷
while (iterator.hasNext()) {
String s = iterator.next();
System.out.println(s);
}
System.out.println("----------");
// 3.jdk5 引入foreach循環
for (String s : list) {
System.out.println(s);
}
System.out.println("----------");
}
- Set: HashSet 使用hashCode和equals 進行排重
TreeSet使用compareable中的compareTo進行排重和排序
對 Set取出遍歷有兩種方法(因爲是無序的,比list少一種方法)
(1)繼承Collection 使用Iterator遍歷
(2)JDK5foreach循環結構
@Test
public void demo3() {
// 使用類型安全的set
Set<String> set = new TreeSet<String>();
set.add("abc");
set.add("def");
set.add("cef");
// 由於 set是無序的 因此 比list 少了一種方法
// 1.set繼承collection 使用 Iterator進行遍歷
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
System.out.println(s);
}
// 2.JDK5 引入foreach循環
for (String s : set) {
System.out.println(s);
}
}
- Map: 是一個鍵值對結構 執行兩個類型的泛型
遍歷方法兩種:
(1)通過keySet
(2)通過 EntrySet取出每一個鍵值對,getKey和getValue
@Test
public void demo5() {
// 使用類型安全的map map 是一個鍵值對結構 執行兩個類型的泛型
Map<String, String> map = new HashMap<String, String>();
map.put("111", "aaa");
map.put("222", "bbb");
// 取出map 兩種方法,
// 1.通過 keyset
Set<String> keys = map.keySet();
for (String s : keys) {
System.out.println(s + ":" + map.get(s));
}
// 2.通過map entrySet 獲得每一個鍵值對
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for (Entry<String, String> entry2 : entrySet) {
System.out.println(entry2.getKey() + ": " + entry2.getValue());
}
}
使用泛型對象進行類型轉換時,等號兩端對象使用泛型的類型必須一致
2. 編寫通用java程序
通常是結合反射技術一起使用
自定義泛型方法
(1)定義泛型方法,必須在方法的返回值前進行泛型類型聲明<泛型類型>
使用泛型方法,參數必須是對象類型
@Test
public void demo7() {
// 將數組元素進行倒序排列
Integer[] arr1 = new Integer[] { 1, 2, 3, 4, 5, 6 };
reverce(arr1);
System.out.println(Arrays.toString(arr1));
String[] arr2 = new String[] { "aa", "bb", "cc", "dd", "ee", "ff" };
reverce(arr2);
System.out.println(Arrays.toString(arr2));
}
// 屬於引用傳遞 不需要返回值
public <T> void reverce(T[] arr) {
/**
* 只需要遍歷數組的前一半的元素,然後和後一半元素進行交換
*
* */
for (int i = 0; i < arr.length / 2; i++) {
T temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
}
@Test
// 交換數組的位置
public void demo6() {
Integer[] arr1 = new Integer[] { 1, 2, 3, 4, 5 };
ChangePosition(arr1, 1, 3);
System.out.println(Arrays.toString(arr1));
String[] arr2 = new String[] { "aa", "bb", "cc", "dd", "ee" };
ChangePosition(arr2, 1, 3);
System.out.println(Arrays.toString(arr2));
}
// 使用泛型交換數組的通用方法
public <T> void ChangePosition(T[] arr, int index1, int index2) {
T temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
(2)在類名後聲明類的泛型,當類使用泛型後,該類中的所有方法都可以使用泛型—在類名後<泛型類型> 不對static方法生效。
public class ArrayUtils<T> {
public void reverce(T[] arr) {
/**
* 只需要遍歷數組的前一半的元素,然後和後一半元素進行交換
*
* */
for (int i = 0; i < arr.length / 2; i++) {
T temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
}
// 使用泛型交換數組的通用方法
public void ChangePosition(T[] arr, int index1, int index2) {
T temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
}
@Test
public void demo8() {
// 測試 泛型類 使用
/*
* 在創建工具類對象時,使用泛型String, 這個工具類對象完成對String數組 倒序和 交換
*/
ArrayUtils<String> arrayutils = new ArrayUtils<String>();
String[] arr1 = new String[] { "aa", "bb", "cc", "dd" };
arrayutils.ChangePosition(arr1, 1, 3);
System.out.println(Arrays.toString(arr1));
arrayutils.reverce(arr1);
System.out.println(Arrays.toString(arr1));
}
3.泛型的高級應用–泛型通配符
?:任意的泛型類型
@Test
public void demo9() {
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
print(list);
List<Integer> list2 = new ArrayList<Integer>();
list2.add(111);
list2.add(222);
list2.add(333);
print(list2);
}
public void print(List<?> list) {// 泛型類型可以是任意類型 --泛型通配符
for (Object string : list) {
System.out.println(string);
}
}