码迷,mamicode.com
首页 > 编程语言 > 详细

java泛型简单学习

时间:2015-11-23 23:39:17      阅读:291      评论:0      收藏:0      [点我收藏+]

标签:

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

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

//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); }

 

java泛型简单学习

标签:

原文地址:http://www.cnblogs.com/shuqingstudy/p/4990015.html

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!