zoukankan      html  css  js  c++  java
  • Java 集合框架之泛型

    1. JDK 1.5 以后出现的安全机制,提高了编译时期的安全性.

    2. 泛型出现的好处:

      1. 将运行时期的问题 ClassCastException 转到了编译时期
      2. 避免了强制转换的麻烦
    3. 泛型出现的原因:

    public static void main(String[] args){
    
        ArrayList al = new ArrayList();
    
        al.add("abc");
        al.add("xyz");
        al.add(4); // 此处存入的为 Integer 类型
    
        Iterator it = al.iterator();
        while(it.hasNext()){
    
            String str = (String)it.next();  // 运行时,出现 ClassCastException 异常
            System.out.println(str);
        }
    }
    
    // 泛型
    
    public static void main(String[] args){
    
        // 在定义集合时, 声明要存储元素的类型
        ArrayList<String> al = new ArrayList<String>();
    
        al.add("abc");
        al.add("xyz");
        al.add(4); // 编译时期,会报错
    
        Iterator<String> it = al.iterator();
        while(it.hasNext()){
    
            String str = it.next();  // 使用泛型之后,此处不需要强转
            System.out.println(str);
        }
    }
    
    1. 泛型什么时候使用?

      1. 当操作的引用数据类型不确定的时候, 就使用<>, 将要操作的引用数据类型传入即可.
        其实 <> 就是一个用于接收具体引用数据类型的参数范围.
      2. 在程序中, 只要使用到了带有 <> 的类或者接口, 就要明确传入的具体引用数据类型
    2. 泛型的擦除和补偿

      • 擦除: 程序运行时,会将泛型去掉, 即生成的 class 文件中是不带泛型的. 为了兼容运行时的类加载器.
      • 补偿: 程序运行时, 类加载器通过 getClass() 方法获取元素的类型,自动进行转换动作, 不需要使用者在强制转换.
    3. 通配符

    // 通配符 ?
    
    public static void main(String[] args){
    
        ArrayList<String> al = new ArrayList();
        al.add("abc");
        al.add("dfd");
    
        HashSet<String> hs = new HashSet();
        hs.add("gfj");
        hs.add("ert");
    
        printCollection(al);
        printCollection(hs);
    
    
    }
    
    // 迭代并打印集合中的元素,
    // 不同的集合均可使用父接口 Collection 接收,提高扩展性
    public static void printCollection(Collection<String> al){
        Iterator<String> it = al.iterator();
    
        while(it.hasNext()){
            System.out.println(it.next());
    }
    }
    
    
    // 通配符的使用
    public static void main(String[] args){
        ArrayList<String> al = new ArrayList();
        al.add("abc");
        al.add("wew");
    
        ArrayList<Integer> al2 = new ArrayList();
        al2.add(3);
        al2.add(4);
    
        printCollection(al);
        printCollection(al2);
    }
    
    // ? 通配符, 也可以理解为占位符,代表未知类型.
    // 提高程序扩展性
    public static void printCollection(Collection<?> al){
        Iterator<?> it = al.iterator();
    
        while(it.hasNext()){
            System.out.println(it.next());
    }
    
    // 或者 泛型定义在方法上, 类型为 T, 注意使用时,需要先在修饰符 static 后面声明
    public static <T> void printCollection(Collection<T> al){
        Iterator<T> it = al.iterator();
    
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
    }
    
    1. 泛型的限定
      • 向上限定: ? extends E , 可以接收 E 类型或者 E 类型的子类型
        一般存储元素的时候都是用上限,因为这样取出都是按照上限类型来运算, 不会出现类型隐患.
        例如 Collection 接口中的 boolean addAll(Collection<? extends E> c) 方法
      • 向下限定: ? super E, 可以接收 E 类型或者 E 类型的父类型.
        通常对集合中的元素进行取出操作时,可以使用下限
        例如 TreeSet 构造方法 TreeSet(Comparator<? super E> comparator)
    // 向上限定, Student 和 Worder 对象都继承自 Person
    
    public static void main(String[] args){
        ArrayList<Worker> al = new ArrayList<Worker>();
        al.add(new Worker("wangcai",32));
        al.add(new Worker("lisi",24));
    
        ArrayList<Student> al2 = new ArrayList<Student>();
        al2.add(new Student("zhangsan",11));
        al2.add(new Student("zhaoliu",26));
    
        printCollection(al);
        printCollection(al2);
    }
    
    // 只打印 Person 对象的子类
    public static void printColletion(Collection<? extends Person> al){
        Iterator<? extends Person> it = al.iterator();
    
        while(it.hasNext()){
            // System.out.println(it.next());
    
            Person p = it.next(); // 因为存入的都是 Person 对象的子类, 所以多态
    
            System.out.println(p.getName()+"..."+p.getAge());
    }
    }
    


    _参考资料_ - [JavaSE 基础视频(毕向东)](https://www.bilibili.com/video/av3120256/#page=9) - [JDK 1.6 中文文档](http://tool.oschina.net/apidocs/apidoc?api=jdk-zh)
  • 相关阅读:
    usaco 1.11
    当数组时全局变量时。。。怎样进行循环初始化
    hdu 1097 用到了位的移动
    hdu 1006
    HNOI2008]神奇的国度
    App测试基本流程详解(汇总整理)
    IOS测试Fastmonkey
    pytest+allure2+jenkins环境部署
    如何在cmd查看文件内容的md5值
    软件测试学习linux基础
  • 原文地址:https://www.cnblogs.com/linkworld/p/7496243.html
Copyright © 2011-2022 走看看