zoukankan      html  css  js  c++  java
  • java泛型简单学习

    一. 泛型概念的提出(为什么需要泛型)?

    首先,我们看下下面这段简短的代码:

    //import java.util.List;
    
    public class GenericTest {
    
        public static void main(String[] args) {
            List list = new ArrayList();
            list.add("语文");
            list.add("数学");
            list.add(100);  //编译错误
    
            for (int i = 0; i < list.size(); i++) {
                String name = (String) list.get(i); // 1
                System.out.println("name:" + name);
            }
        }
    }

    定义了一个List类型的集合,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时list默认的类型为Object类型。在之后的循环中,由于忘记了之前在list中也加入了Integer类型的值或其他编码原因,很容易出现类似于//1中的错误。因为编译阶段正常,而运行时会出现“java.lang.ClassCastException”异常。因此,导致此类错误编码过程中不易发现。

     在如上的编码过程中,我们发现主要存在两个问题:

    1.当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。

    2.因此,//1处取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现“java.lang.ClassCastException”异常。

    那么有没有什么办法可以使集合能够记住集合内元素各类型,且能够达到只要编译时不出现问题,运行时就不会出现“java.lang.ClassCastException”异常呢?答案就是使用泛型。

    二.什么是泛型?

    泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

     看着好像有点复杂,首先我们看下上面那个例子采用泛型的写法。

    public static void main(String[] args) {
        
            List<String> list = new ArrayList<String>();//2
            
            list.add("语文");
            list.add("数学");
            list.add("英语");
            //list.add(100);//1 编译错误
            
            //输出
            for(int i=0 ; i<list.size();i++){
                String subjectName = list.get(i);//3
                System.out.println("科目名称:"+subjectName);
                
            }
        }

    1. 程序//1处试图将一个Integer对象添加到list集合中,程序将无法通过编译,报出:
        java.lang.Error: Unresolved compilation problem
        因为list只接受String对象作为元素,所以//1处代码在编译时会得到错误提示

    2.所以要使用泛型,如程序2处创建一个特殊的List集合:list,这个List集合只能保存字符串对象,不能保存其他类型的对象
       创建这种特殊集合的方式是:在集合接口、类后增加尖括号,尖括号里放一个数据类型,即表示这个集合接口、结合类只能保存特定类型的对象
       如//2处的类型声明,它指定:list不是一个任意的list,而是一个String类型的list,写作List<String>.我们认为list是带一个类型参数的泛型接口

    3.程序在//3处不需要进行强制类型转换,因为list对象可以“记住”它的所有集合元素都是String类型

    结合上面的泛型定义,我们知道在List<String>中,String是类型实参,也就是说,相应的List接口中肯定含有类型形参。且get()方法的返回结果也直接是此形参类型(也就是对应的传入的类型实参)。

    三、JAVA 7泛型的“棱形”写法

    在java 7以前,如果使用带泛型的接口、类定义变量,那么调用构造器创建对象时构造器的后面也必须带泛型,则显得有些多余,例如:

    List<String> strList = new ArrayList<String>();
    Map<String ,Interger> scores = new HashMap<String ,Integer>();

    上面两条语句中的粗体代码部分是完全多余的,在java 7以前这是必需的,不能省略。java 7以后,只要给出一对尖括号(<>)即可,java可以
    推断出尖括号里应该是什么泛型信息。即上面两条语句可以改为如下形式:

    List<String> strList = new ArrayList<>();
    Map<String ,Interger> scores = new HashMap<>();

    因而简化代码:

    List<String> list = new ArrayList<>();//1
            
            list.add("语文");
            list.add("数学");
            list.add("英语");
            //list.add(100);//2
            
            //输出
            for(int i=0 ; i<list.size();i++){
                String subjectName = list.get(i);//3
                System.out.println("科目名称:"+subjectName);
                
            }

     Double泛型:

       List<Double> list = new ArrayList<>();//2
            
            list.add(10.1);
            list.add(10.2);
            list.add(10.3);
            //list.add(100);//1
            
            //输出
            for(int i=0 ; i<list.size();i++){
                Double subjectName = list.get(i);//3
                System.out.println("科目成绩:"+subjectName);
                
            }

    键值对:

    java中的map其实就是以键值对形式的存放数据的容器,其常用的实现类主要是哈希map
    例如:
    Map map = new HashMap();
    插入元素:map.put("key", obj); 
    移除元素: map.remove("key");
    清空: map.clear();

    import java.util.HashMap;
    import java.util.Map;


    Map<String,Double> list = new HashMap<>();//2 list.put("语文",10.1); list.put("数学",10.1); list.put("英语",100.0); String arr[]={"语文","数学","英语"}; //输出 for(int i=0 ; i<list.size();i++){ Double subjectName = list.get(arr[i]);//必须是键值对 System.out.println("科目成绩:"+subjectName); }
  • 相关阅读:
    Redis(五)——主从做读写分离原理与优化
    Redis(四)——持久化方案(RDB和AOF使用)
    Redis(三)——高级用法(GEO地理位置信息)
    Redis(二)——五大数据类型的基本操作(字符串类型,哈希类型,列表类型,集合类型,有序集合类型)
    Redis(一)——redis初识,redis安装和启动
    15 Ajax技术
    ORM多表分组、F与Q查询
    ORM多表操作
    ORM单表操作
    CentOS 7 下 rdesktop 的安装
  • 原文地址:https://www.cnblogs.com/shuqingstudy/p/4990015.html
Copyright © 2011-2022 走看看