泛型

應用:
1. 類型安全檢查
2. 編寫通用Java程序

  1. 類型安全檢查
    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進行類型安全檢查

  1. 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("----------");
    }
  1. 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);
        }
    }
  1. 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);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章