栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java学习笔记Day13 泛型

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java学习笔记Day13 泛型

泛型 Generic

所谓泛型就是允许在定义类,接口时通过一个标志表示类中某个属性的类型或者是某个方法的返回值及参数类型。这个参数类型将在使用时(如继承或实现这个接口,用这个类型声明变量,创建对象时)确定传入实际的类型参数,也称为类型实参。

例:

@Test
    public void test() {
        //在集合中使用泛型之前
        ArrayList arrayList = new ArrayList();
        //在集合中存放学生成绩
        arrayList.add(65);
        arrayList.add(80);
        arrayList.add(99);
        arrayList.add(59);

        //类型不安全
        //arrayList.add("surprise");

//        for (Object o : arrayList) {
//            //强转时可能出现ClassCastException
//            int score = (Integer) o;
//            System.out.println(score);
//        }

        //在集合中使用泛型 ArrayList
        ArrayList arrayList1 = new ArrayList();
        arrayList1.add(65);
        arrayList1.add(80);
        arrayList1.add(99);
        arrayList1.add(59);

        //会报错无法添加 保证数据安全
        //arrayList1.add("surprise");

        //无需强转
//        for (Integer score : arrayList1) {
//            System.out.println(score);
//        }

//        Iterator iterator = arrayList1.iterator();
//        while (iterator.hasNext()) {
//            System.out.println(iterator.next());
//        }

        //在集合中使用泛型 HashMap
        HashMap hashMap = new HashMap<>();
        hashMap.put(1, "GYQ");
//        hashMap.put("2", 123);  //会报错
        hashMap.put(3, "GQ");
        hashMap.put(4, "GY");

        Set> entries = hashMap.entrySet();
        Iterator> iterator = entries.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

总结:集合接口或集合类在jdk5.0时都修改为带泛型的结构。

           在实例化集合类时,可以指明具体的泛型类型

           指明完以后,在集合类或接口中凡是定义类或接口时,内部结构使用到类的泛型的位置,都指定为实例化时的泛型类型。比如:add(E e) --->实例化以后:add(Integer e)

           泛型的类型必须是一个类,不能是基本数据类型(用包装类)

           如果实例化时没有指明泛型的类型,则默认为java.lang.Object类型

泛型的使用

 @Test
    public void test() {
        //TreeSet treeSet = new TreeSet();
        //jdk7新特性:类型推断
        TreeSet treeSet = new TreeSet<>();
        treeSet.add(new Employee("gyq", 10000));
        treeSet.add(new Employee("clv", 777));
        treeSet.add(new Employee("uzi", 888));
        treeSet.add(new Employee("zzt", 555));
        treeSet.add(new Employee("hib", 999));
        //自然排序的结果
        Iterator iterator = treeSet.iterator();
        while (iterator.hasNext())
            System.out.println(iterator.next());
        System.out.println("--------------------");

        //定制排序
        TreeSet treeSet1 = new TreeSet<>(new Comparator() {
            //按salay从高到低
            @Override
            public int compare(Employee o1, Employee o2) {
                return -Integer.compare(o1.salary, o2.salary);
            }
        });
        treeSet1.add(new Employee("gyq", 10000));
        treeSet1.add(new Employee("clv", 777));
        treeSet1.add(new Employee("uzi", 888));
        treeSet1.add(new Employee("zzt", 555));
        treeSet1.add(new Employee("hib", 999));

        //定制排序的结果
        Iterator iterator1 = treeSet1.iterator();
        while (iterator1.hasNext())
            System.out.println(iterator1.next());
    }
}

class Employee implements Comparable {
    public String name;
    public int salary;

    public Employee(String name, int salary) {
        this.name = name;
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + ''' +
                ", salary=" + salary +
                '}';
    }

    //按照name排序
    @Override
    public int compareTo(Employee o) {
        return this.name.compareTo(o.name);
    }
自定义泛型结构:泛型类,泛型接口,泛型方法
public class TestClass {
    @Test
    public void test() {
        //带泛型类的使用
        Class Class1 = new Class<>(1, "软工", "gyq");
        Class Class2 = new Class<>(1, "软工", 1);
        System.out.println(Class1);
        System.out.println(Class2);

        //泛型不同的引用不能相互赋值
        ArrayList list = null;
//        ArrayList list1 = list; 报错

        //继承带泛型类的类的使用
        //由于子类在继承带泛型的父类时,指明了泛型类型,则实例化时不需要指明
//        subClass subClass1 = new subClass();
//        subClass1.setMonitor(10.0);

        //由于子类在继承带泛型的父类时,没有指明泛型
        subClass subClass2 = new subClass();
        subClass2.setMonitor("wms");
    }
}

class Class {
    int cno;
    String major;
    //类内部结构就可以使用类的泛型
    T monitor;

    //非静态方法可以使用
    public T getMonitor() {
        return monitor;
    }

    //静态方法 无法使用类的泛型
//    public static T getMonitor() {
//        return monitor;
//    }

    public Class() {
    }

    public Class(int cno, String major, T monitor) {
        this.cno = cno;
        this.major = major;
        this.monitor = monitor;
    }

    public void setMonitor(T monitor) {
        this.monitor = monitor;
    }

    @Override
    public String toString() {
        return "Class{" +
                "cno=" + cno +
                ", major='" + major + ''' +
                ", monitor=" + monitor +
                '}';
    }
}

//继承时指明泛型
//class subClass extends Class

//不指明泛型 此时subClass仍是泛型类
class subClass extends Class {

}

补充:

泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:

泛型的构造器如下:public GenericClass(){};  不需要加尖括号,但在使用时需要加。

实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致。

泛型不同的引用不能相互赋值。

泛型如果不指定将被擦除,泛型对应的类型均按照Object处理,但不等价于Object。经验:泛型要使用一路都要用,要不用,一路都不用。

如果泛型结构是一个接口或抽象类,则不可创建该结构的对象

在接口/类上声明的泛型,在本类或本接口中可以作为非静态属性的类型,非静态方法的参数类型,返回值。但在静态方法中不能使用泛型。 静态方法早于对象的创建,泛型在对象创建是指定类型

异常类不能是泛型的

声明泛型类数组:

        不能使用 T[ ] array = new T[capacity] 应该使用 T[ ] array = (T[ ])new Object[capacity]

父类中有泛型,子类可以选择保留泛型也可以指定泛型类型

泛型方法

不是说方法中使用了泛型就叫泛型方法,泛型方法可以是静态的

public class TestClass {
    @Test
    public void test() {
        Integer[] iarr = new Integer[]{1, 2, 3, 4, 5, 6};
        String[] sarr = new String[]{"ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX"};
        HashMap map1 = toMap(sarr, iarr);
        HashMap map2 = toMap(iarr, sarr);
        System.out.println(map1);
        System.out.println(map2);
    }

    //在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系
    //换句话说,泛型方法所属的类是不是泛型类都没关系
    public  HashMap toMap(A[] key, B[] value) {
        HashMap map = new HashMap();
        for (int i = 0; i < key.length; i++) {
            map.put(key[i], value[i]);
        }
        return map;
    }
}
泛型在继承方面的体现

虽然类A是类B的父类,但是G 和 G 没有子父类关系,两者为并列的关系

类A是类B的父类,A和B是子父类的关系

    @Test
    public void test() {
        Object obj = null;
        String str = null;
        obj = str;

        Object[] arr1 = null;
        String[] arr2 = null;
        arr1 = arr2;

        List list1 = null;
        List list2 = null;
        //此时list1和list2是两个并列的结构 和下方举例都编译不通过
//        list1 = list2;

        //两者没有任何子父类关系
//        LocalDateTime DateTime = LocalDateTime.now();
//        DateTime = str;

        //此时 AbstractList 和 ArrayList 仍是子父类关系
        AbstractList list = null;
        ArrayList arrayList = null;
        list = arrayList;
    } 
通配符的使用 

G 和 G 的公共父类 G

public class TestClass {
    @Test
    public void test() {
        List list1 = new ArrayList<>();
        list1.add("123");
        list1.add("234");
        list1.add("345");

        List list2 = new ArrayList<>();
        list2.add(1);
        list2.add(2);
        list2.add(3);

        show(list1);
        System.out.println("------------");
        show(list2);
        System.out.println("------------");


        //使用通配符后添加数据和读取数据的要求
        List list = null;
        list = list1;
        //对于List不能向其内部添加数据,除了添加null之外
//        list.add("str");
        list.add(null);

        //读取
        Object o = list.get(0);
        System.out.println(o);

    }

    public void show(List list) {
        for (Object o : list) {
            System.out.println(o);
        }
    }
}
有限制的通配符

通配符指定上限

上限extends:使用时指定的类型必须是继承某个类,或者实现某个接口,即<=

通配符指定下限

下限super:使用时指定的类型不能小于操作的类,即>=

public class TestClass {
    @Test
    public void test() {
        List List1 = new ArrayList<>();
        List List2 = new ArrayList<>();


        List List3 = new ArrayList<>();
        List List4 = new ArrayList<>();
        List List5 = new ArrayList<>();

        //将三种的List分别赋给要求泛型类型小于等于Person的List1
//        List1=List3;  //Object 不符合
        List1 = List4;
        List1 = List5;

        //将三种的List分别赋给要求泛型类型大于等于Person的List2
        List2 = List3;
        List2 = List4;
//        List2 = List5; //Man 不符合

        //读取   接收的类型要>=指定的范围
        Person person = List1.get(0);
        Object obj = List1.get(0);

        Object object = List2.get(0);

        //添加
        //List1表示只允许泛型<=Person的引用调用,则他可能是任意一个无穷小
        //不能用范围小的指向范围大的引用
//        List1.add(new Object());
//        List1.add(new Person());
//        List1.add(new Man());

        //List2表示只允许>=Person的引用调用,所以可以添加Person及其子类
//        List2.add(new Object());
        List2.add(new Person());
        List2.add(new Man());
    }
}

class Person {

}

class Man extends Person {

}

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号