第十三章 泛型

1.练习回顾

public class Test {
    public static void main(String[] args) {
        List<Student> list = new LinkedList<>();
        list.add(new Student("A01","xxx1",19));
        list.add(new Student("A01","xxx2",17));
        list.add(new Student("A01","xxx3",18));
        list.add(new Student("A02","xxx4",19));
        list.add(new Student("A02","xxx5",20));


        Map<String,String> map = new HashMap<>();
        Iterator<Student> it = list.iterator();
        while (it.hasNext()){
            Student s = it.next();
            if (map.containsKey(s.getClas())){
                map.put(s.getClas(),map.get(s.getClas())+","+s.getName());
                continue;
            }
            map.put(s.getClas(),s.getName());
        }

        Iterator<String> it1 = map.keySet().iterator();
        while (it1.hasNext()){
            String s = it1.next();
            System.out.println(s+"--->"+map.get(s));
        }
    }
}
public class Student {
    private String clas;
    private String name;
    private int age;

    public Student(String clas, String name, int age) {
        this.name = name;
        this.clas = clas;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClas() {
        return clas;
    }

    public void setClas(String clas) {
        this.clas = clas;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", clas='" + clas + '\'' +
                ", age=" + age +
                '}';
    }
}

 Hash Map:


全网把Map中的hash()分析的最透彻的文章,别无二家。-HollisChuang's Blog你知道HashMap中hash方法的具体实现吗?你知道HashTable、ConcurrentHashMap中hash方法的实现以及原因吗?你知道为什么要这么实现吗?你知道为什么JDK 7和JDK 8中hash方法实现的不同以及区别吗?如果你不能很好的回答这些问题,那么你需要好好看看这篇文章。文中涉及到大量代码和计算机底层原理知识。绝对的干货满满。整个互联网,把hash()分析的如此透彻的,别无二http://www.hollischuang.com/archives/2091

http://t.csdn.cn/xSgRehttp://t.csdn.cn/xSgRe

2.泛型具体内容 

2.1 泛型产生的意义

泛型是在JDK1.5之后增加的新功能,

意义:保证数据的安全性;

基本使用:由外部指定其具体的操作类型。

2.2 使用泛型类

        (设计一个坐标点的类,坐标由X和Y组成,x,y的取值可以时数字,小数和字符串);在这样的需求下,可以使用泛型类来进行设计。

public class Position<T> {
    private T x;
    private T y;
    
    //构造方法的参数使用泛型
    public Position(T x, T y) {
        this.x = x;
        this.y = y;
    }

    public T getX() {
        return x;
    }

    public void setX(T x) {
        this.x = x;
    }

    public T getY() {
        return y;
    }

    public void setY(T y) {
        this.y = y;
    }

    @Override
    public String toString() {
        return "Position{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
}

在泛型类中同时指定多个类型

public class Notepad<K,V>{
    private K key;
    private V value;

    public Notepad(K key,V value){
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return key;
    }

    public void setKey(K key) {
        this.key = key;
    }

    public V getValue() {
        return value;
    }

    public void setValue(V value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Notepad{" +
                "key=" + key +
                ", value=" + value +
                '}';
    }
}

2.3 泛型擦除

        Java中的泛型只在源码中存在,编译的时候静态地检查一下泛型类型是否正确;在运行时,Java不会保留泛型。

    public static void main(String[] args) {
        List<Integer> list = new LinkedList<>();
        list.add(123);
        list.add(321);
        //list.add("aaa");
        
        //泛型被擦除
        List list2 = list;
        list2.add("aaa");
        list2.add("ccc");

        System.out.println(list);
    }

目的:

为了向下兼容,在Java 5 才引入泛型,引入泛型是为了解决遍历集合的时候总要手动强制转型的问题。

2.4 泛型通配符  ?

        在程序开发中对象的引用传递是最常见的,但是如果方法参数是泛型类对象,则传入的泛型数据必须匹配才可以,否则无法传递。

public class Test {
    public static void main(String[] args) {
        Info<String> i = new Info<>();
        i.setVar("wen");
        
        //泛型类型不一致,报错
        //fun(i);
    }
    public static void fun(Info<Object> info){
        System.out.println(info);
    }
}

         一个类的子类可以通过对象多态化,为其父类实例化,但在泛型操作中,子类的泛型类型无法使用父类的泛型类型接受。

如果方法的参数没有指定泛型的时候,可以是使用擦除泛型的特性传递参数。

    public static void fun(Info info){
        System.out.println(info);
    }

使用 ?  通配符设置泛型类型,接受泛型参数。

    public static void fun(Info<?> info){
        System.out.println(info);
        //使用通配符 ? 可以接受任意泛型参数,但是此时是泛型对象不能修改数据
        //info.setVar("mu");
    }

2.5 受限泛型

        在引用传递的过程中,泛型操作也可以设置一个泛型对象的范围上限和范围下限,范围上限使用extends关键字声明,表示参数化的类型可能是所指的类型,或者此类型的子类,而范围下限使用super进行声明,表示参数化的类型可能是所指的类型,或者此类型的父类型,直至Object类型。

2.5.1 设置泛型上限

    public static void main(String[] args) {

        Info<Integer>  i1 = new Info<>();
        i1.setVar(100);
        fun(i1);

        Info<Double> i2 = new Info<>();
        i2.setVar(12.13);
        fun(i2);
    }
    
    //设置范围上限是Number,只能接受数字类型
    public static void fun(Info<? extends Number> info){
        System.out.println(info);
    }
//也可以直接定义在类里,设置好泛型范围
public class Info<T extends Number> {
    private T var;

    public T getVar(){
        return var;
    }

    public void setVar(T var){
        this.var = var;
    }

    @Override
    public String toString() {
        return "Info{" +
                "var=" + var +
                '}';
    }
}

2.5.2 设置泛型下限

        使用泛型只能在本类及其父类类型上应用的时候,就必须使用泛型的范围下限配置。(不能再定义类的时候使用下限定义,只能用?方式定义)

public class Test1 {
    public static void main(String[] args) {
        Info<String> i1 = new Info<>();
        i1.setVar("wen");
        fun(i1);

        Info<Object> i2 = new Info<>();
        i2.setVar("mu");
        fun(i2);

    }
    public static void fun(Info<? super String> info){
        System.out.println(info);
    }
}

 2.6 泛型方法

        针对某个方法设置泛型

public class Info2 {
    //泛型方法,无返回值
    public <T> void test(T val){
        System.out.println(val);
    }
    
    //返回字符串的泛型方法
    public <T> String test2(T val){
        return val.toString();
    }
    
    //返回任意类型的泛型方法
    public <T> T test3(T val){
        return val;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值