Java集合框架篇Collection—泛型

泛型

  • 用于解决安全问题,可以看做一个安全机制
  • 三种使用方式,分别为:泛型类、泛型接口、泛型方法

    先举一个例子:

ArrayList<String> al = new ArrayList<String>();
//这句话的意思就是,定义了一个ArrayList容器,容器中的元素是String类型

那么它解决了什么问题呢?
再举一个例子:

import java.util.*;

class GenericsDemo{
    public static void main(String[] args){
        ArrayList<String> a1 = new ArrayList<String>();
        //ArrayList a1 = new ArrayList();

        a1.add("123");
        a1.add("312");
        a1.add(123); 

        for(Iterator<String> it = a1.iterator();it.hasNext();){
            String s = it.next();
            System.out.println(s);
        }
    }
}

我们可以看到在编译的时候控制台就会报异常,但是用第二句不用泛型呢,你会看到可以编译通过,控制台之后给你一个不安全操作的提示,但是当你运行的时候一样会报ClassCastException

如果你说你就是要存入不同数据类型的元素,这当然也是可以,但是没啥用,因为元素间不能比较,就只能存进去,然后打印出来。建议用StringBuffer或StringBuilder。

  • 所以泛型首先能够让我们更快的发现解决问题,让运行问题减少,安全。
  • 其次,它避免了强制转换的麻烦。
import java.util.*;

class GenericsDemo2{
    public static void main(String[] args){
        TreeSet<String> a1 = new TreeSet<String>(new LenComparator());

        a1.add("312");
        a1.add("sd");
        a1.add("sad");
        a1.add("12ewr");

        for(Iterator<String> it = a1.iterator();it.hasNext();){
            String s = it.next();
            System.out.println(s);
        }
    }
}

class LenComparator implements Comparator<String>{
    public int compare(String s1,String s2){
        int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
        if(num == 0)
            return s1.compareTo(s2);
        return num;
    }
}

Interface Comparator<T>
从它的使用就可以看出<>可以接受一个引用数据类型(注意基础数据类型是不行的)

泛型使用

  • 泛型类:在整个类中都有效,如果被方法调用那么泛型类的对象明确要操作的具体类型后,所有的操作类型就固定了。
  • 泛型方法:为了让不同的方法可以操作不同类型,而且类型还不明确,那么可以将泛型定义在方法上。
  • 静态方法不可以访问类上定义的泛型,如果静态方法操作的数据类型不确定可以使用泛型方法。
  • <T>放的位置是返回值前修饰符后
  • 泛型接口:和泛型类作用一样
class GenericsDemo3{
    public static void main(String[] args){
        new Demo1<String>().print("123");
        new Demo1<String>().show(123);

        new Demo2().print(123);
        new Demo2().print("123");
        new Demo2().show(123);
        new Demo2().show("123");

        new Demo3<String>().print("123");
        new Demo3<String>().show(123);
        new Demo3<String>().method(123);
    }
}

//泛型定义在类上
class Demo1<T>{
    public void print(T t){
        System.out.println(t);
    }
    public void show(int t){
        System.out.println(t);
    }
}

//泛型定义在方法上
class Demo2{
    public <T> void print(T t){
        System.out.println(t);
    }
    public <Q> void show(Q t){
        System.out.println(t);
    }
}

class Demo3<T>{
    public void print(T t){
        System.out.println(t);
    }
    public <Q> void show(Q t){
        System.out.println(t);
    }
    //静态得先加载 所以不能访问类上的泛型T
    public static <W> void method(W w){
        System.out.println(w);
    }
}

//泛型定义在接口上
interface inte<T>{
    void show(T t);
}

class inteimpl<T> implements inte<T>{
    public void show(T t){
        System.out.println("show:"+t);
    }
}

泛型中的符号

  • 泛型中<E> <T> 代表Element和Type
  • 泛型中还有一个通配符/占位符 表示在不能明确数据类型的情况下表示
import java.util.*;

class GenericsDemo5{
    public static void main(String[] args){
        ArrayList<String> a1 = new ArrayList<String>();
        ArrayList<Integer> a2 = new ArrayList<Integer>();

        a1.add("aa11");
        a1.add("aa12");
        a1.add("aa13");
        a2.add(11);
        a2.add(12);
        a2.add(3);

        print(a1);
        // print(a2);
    }


    public static void print(ArrayList<String> a1){
        for (Iterator<String> it = a1.iterator();it.hasNext() ; ) {
            System.out.println(it.next().length());
        }
    }

    public static void print(ArrayList<?> a1){
        for (Iterator<?> it = a1.iterator();it.hasNext() ; ) {
            System.out.println(it.next());
        }
    }

    public static <T> void print2(ArrayList<T> a1){
        for (Iterator<T> it = a1.iterator();it.hasNext() ; ) {
            T t = it.next();
            try{
                System.out.println(t instanceof String);
            }catch(Exception e){}
        }
    }
}
  • 泛型属于多态的一种表现形式,所以它也不能预先使用子类其特有的方法。(函数重载、继承/方法重写、运算符重载等一样)

泛型的限定

  • 泛型的限定是为了限定泛型,扩展。
  • <? extends E> 可以接受E类型或E的子类型,上限。
  • <? super E> 可以接受E类型或E的父类型,下限。

猜你喜欢

转载自blog.csdn.net/bfinwr/article/details/79405147