Java_泛型_总结

Java_泛型(Generic)

本文主要是对泛型的初学简单做一个总结吖~
对于常见的泛型模式,推荐的泛型类型变量:
E:元素(Element),多用于java集合框架
K:关键字(Key)
N:数字(Number)
T:类型(Type)(通用)
V:值(Value)


为什么要使用泛型?

泛型是我们需要的程序设计手段。使用泛型机制编写的程序代码要比那些杂乱地使用Object变量,然后再进行强制类型转的代码具有更好的安全性和可读性。泛型对于集合类尤其有用。


举个栗子:
public class ListDemo {
    //      集合不使用泛型
    public void test1() {
        ArrayList list = new ArrayList();
        //存放的实际上是integer类型
        list.add(12);
        list.add(23);
        list.add(34);
        list.add(45);
        //问题一:类型不安全
        list.add("Tom");

        for (Object score : list) {
            //问题二:强转时,可能出现ClassCastException
            int stuScore = (Integer) score;
            System.out.println(stuScore);
        }
    }

    //    集合使用泛型。
    public void test2() {
        ArrayList<Integer> list = new ArrayList<Integer>();

        list.add(78);
        list.add(87);
        list.add(99);
        list.add(65);
        //编译时,就会进行类型检查,保证数据的安全
//        list.add("小伙儿");

        //方式一:
        for(Integer score : list){
//        避免了强转操作
        int stuScore = score;
        System.out.println(stuScore);
        }
        //方式二:
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            int stuScore = iterator.next();
            System.out.println(stuScore);
        }

    }

    public static void main(String[] args) {
        ListDemo listDemo = new ListDemo();
        listDemo.test1();
        listDemo.test2();
    }
}

当test1()方法中,即添加了int类型的数据,又添加了String数据的时候就会出现如下结果。
结果1:
结果1当test2()方法中,如果使用泛型,会再直接报错,不会再运行时才显示。
结果2

泛型程序设计(Generic programming)意味着编写的代码可以被很多不同类型的对象所重用。

一、泛型方法

泛型方法与泛型类、接口等均无关系。
泛型方法概述
由下可以看出,不管此类是不是泛型类,泛型方法均与此类是否定义为泛型类无关。

public class GenericMethodDemo {
    //    泛型方法
    public <T> void show(String t) {
        System.out.println("【泛型方法】返回值为void。" + t);
    }

    public <T> T shows(T t) {
        System.out.println("【泛型方法】返回值为泛型");
        return t;
    }

    public static <T> T staticShow(T t) {
        System.out.println("【泛型方法】static修饰的泛型方法,返回值为泛型");
        return t;
//    不可用
//    public static <T> E staticShow(E t) {
//        System.out.println("【泛型方法】定义为T的泛型方法,返回值为泛型E时不可用");
//        return t;
//    }
    }
}    

静态泛型方法:

public class GenericMethodDemo {
 public static <T, E> E staticShow(E t) {
        System.out.println("【泛型方法】定义为T、E的泛型方法,返回值可以为任意一个类型,传的参数也可以为两种泛型的一个,但是不能为其它泛型");
        return t;
    }
    public static <T, E> T staticShow(T t) {
        return t;
    }
    public static <T, E> T staticShow(E t) {
        T s;
        return s;
    }
}

二、泛型使用

1. 子类处理父类中的泛型

代码如下(示例):

//泛型父类
public class GenericDemoFather<M,N> {
    M a;
    N b;
}

子类处理泛型父类的各种方式如下。

public class GenericDemoSon extends GenericDemoFather<Integer,String>{
//    extends继承时明确父类的类型
}
public class GenericDemoSon<M> extends GenericDemoFather<M,String>{
//    父类保持泛化,子类需要保持泛化。
}

public class GenericDemoSon<N> extends GenericDemoFather<Integer,N>{
//    父类保持泛化,子类需要保持泛化。
}

public class GenericDemoSon<M,N> extends GenericDemoFather<M,N>{
//    父类保持完全泛化,子类保持完全泛化。
}

public class GenericDemoSon<M,N> extends GenericDemoFather<N,M>{
//    父类保持完全泛化,子类保持完全泛化。与顺序无关。
}
public class GenericDemoSon<T> extends GenericDemoFather{
//  子类可以拥有自己的泛型
}
public class GenericDemoSon<T,E> extends GenericDemoFather<Integer,String>{
//  父类类型明确,子类仍可以拥有自己的泛型,且不需要保持父类的类型
}

2.泛型使用举例

代码如下(示例):


public class GenericMethodDemo {

    /**
     * 类型变量的限定
     * 为什么使用extends,而不用implements?(Comparable是一个接口)
     * 其更接近于子类的概念。
     */
//    传入的数组进行最大最小值的比较
    public static <T extends Comparable> MaxiAndMinimum<T> minAndmax(T[] arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }
        T max = arr[0];
        T min = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (min.compareTo(arr[i]) > 0) {//compareTo() 方法用于两种方式的比较
                min = arr[i];
            }
            if (max.compareTo(arr[i]) < 0) {
                max = arr[i];
            }
        }
        return new MaxiAndMinimum<>(min, max);
    }
}

/**
 * 泛型类:求最大最小值的类
 */
class MaxiAndMinimum<T> {
    private T mininum;//最小值
    private T maxinum;//最大值

    //带参的构造函数
    public MaxiAndMinimum(T mininum, T maxinum) {
        this.mininum = mininum;
        this.maxinum = maxinum;
    }

    @Override
    public String toString() {
        return "MaxiAndMinimum{" +
                "mininum=" + mininum +
                ", maxinum=" + maxinum +
                '}';
    }

    public T getMininum() {
        return mininum;
    }

    public void setMininum(T mininum) {
        this.mininum = mininum;
    }

    public T getMaxinum() {
        return maxinum;
    }

    public void setMaxinum(T maxinum) {
        this.maxinum = maxinum;
    }
}

/**
 * 测试主类
 */

class GenericTest<T> {
    //    static 修饰的变量不可以为泛型类型
//    public static T data;
    public static void main(String[] args) {
		showGenericBaseDemo();
        GenericTest genericTest = new GenericTest();
        genericTest.showMinMaxDemo();//调用求最大最小值方法
    }

    //自定义泛型方法等的例子
    public static <T> void showGenericBaseDemo() {
        GenericMethodDemo genericMethodDemo = new GenericMethodDemo();
        genericMethodDemo.show("【结果】方法调用传入的参数为String,返回类型未指定");
        genericMethodDemo.<String>show("【结果】方法调用传入的参数为String,返回类型指定为String");
        System.out.println();
        System.out.println("下面的方法,返回类型指定为Object");
        System.out.println(genericMethodDemo.<Object>shows(new GenericDemo<Integer>()));
        System.out.println(genericMethodDemo.shows(100));
        System.out.println(GenericMethodDemo.<Integer>staticShow(123));
    }

    //    显示一个已知数组的最大最小值
    public void showMinMaxDemo() {

//        创建一个数组 求此数组最大最小值
        Integer[] arr = {12, 34, 23, 67, 21, 87, 9};//要使用包装类而不是基本数据类型
        System.out.println("===============================");
        System.out.println("原数组:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
        System.out.println();
        MaxiAndMinimum<Integer> genericMethodDemoArr = GenericMethodDemo.minAndmax(arr);
        System.out.println("最小值:" + genericMethodDemoArr.getMininum());
        System.out.println("最大值:" + genericMethodDemoArr.getMaxinum());
        System.out.println("使用toString方法输出结果。" + genericMethodDemoArr.toString());
        System.out.println("==============================");
    }
}

结果:

【泛型方法】返回值为void。【结果】方法调用传入的参数为String,返回类型未指定
【泛型方法】返回值为void。【结果】方法调用传入的参数为String,返回类型指定为String
下面的方法,返回类型指定为Object
【泛型方法】返回值为泛型
com.company.day0330.GenericDemo@1b6d3586
【泛型方法】返回值为泛型
100
【泛型方法】static修饰的泛型方法,返回值为泛型
123
原数组:
12 34 23 67 21 87 9
最小值:9
最大值:87
使用toString方法输出结果。MaxiAndMinimum{mininum=9, maxinum=87}


三、泛型(集合的嵌套)

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

//student 类
public class Student {
    private String name;
    private double score;

    public Student(String name, double score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

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

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

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

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (obj instanceof Student) {
            Student s = (Student) obj;
            if (this.name.equals(s.getName()) ) {
                return true;
            }
        }
        return false;
    }

}
public class ListDemo2 {
    
//  集合的嵌套
    public void CollectionNesting(){
//        课程的一个大类subjects-    ArrayList<Student>
        ArrayList<Integer> arrayList = new ArrayList<>();

        ArrayList<ArrayList<Student>> subjects = new ArrayList<>();
        //  创建小集合  课程班级1   classes1
        ArrayList<Student> classes1 = new ArrayList<>();
        //  把学生装进课程班级1
        classes1.add(new Student("凉凉", 80));
        classes1.add(new Student("鲨鲨", 79));
        //  创建课程班2  classes2
        ArrayList<Student> classes2 = new ArrayList<>();
        classes2.add(new Student("杏杏", 73));
        classes2.add(new Student("憨憨", 84));
        //  把学生放进课程2班
        subjects.add(classes1);
        subjects.add(classes2);
        //  遍历打印
        //  一层循环 把课程班找出来
        for (ArrayList<Student> classes : subjects) {
            //  二层循环 把班里学生找出来
//            System.out.println(classes);
            for (Student student : classes) {
                System.out.print("*");
                System.out.println(student);
            }
            System.out.println("==========");
        }
    }

    public static void main(String[] args) {
        ListDemo2 listDemo2 = new ListDemo2();
        listDemo2.CollectionNesting();
    }
}

上述代码主要是集合的嵌套的一个简单例子,使用泛型编写集合的嵌套就会很清晰并且很好用~
上述结果:

*Student{name=‘凉凉’, score=80.0}
*Student{name=‘鲨鲨’, score=79.0}
==========
*Student{name=‘杏杏’, score=73.0}
*Student{name=‘憨憨’, score=84.0}
==========

本文主要通过上述的例子来对泛型进行一定的了解与认识。当然,泛型还有许多需要学习的知识,尤其是与集合的结合运用是Java开发中一个重要的知识部分。后续还会进行深入学习,这次就先写这些吧~
欢迎留言点赞收藏吖~

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值