泛型语法

SOBER大约 4 分钟

泛型语法

介绍

Generic03.java

  1. 泛型又称参数化类型,是Jdk5.0 出现的新特性,解决数据类型的安全性问题
  2. 在类声明或实例化时只要指定好需要的具体的类型即可。
  3. Java 泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生 ClassCastException 异常。同时,代码更加简洁、健壮
  4. 泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值的类型,或者是参数类型。

泛型的声明

interface 接囗 <T>{} 和 class 类 <K,V>{}

比如: List , ArrayList

说明:

  1. 其中,T, K, V 不代表值,而是表示类型。
  2. 任意字母都可以。常用 T 表示,是 Type 的缩写

泛型的实例化

要在类名后面指定类型参数的值(类型)。

  1. List<String>strList = new ArrayList<String>();
    
  2. lterator<Customer>iterator = customers.iterator();
    

练习题

创建 3个学生对象放入到 HashSet 中学生对象,使用 . 放入到 HashMap 中,要求 Key 是 String name,Value 就是 学生对象使用两种方式遍历

package commonGenericity;

import java.util.*;

public class GenericExercise {
    public static void main(String[] args) {
        HashSet<Student> students = new HashSet<Student>();
        students.add(new Student("Jack", 23));
        students.add(new Student("Tom", 24));
        students.add(new Student("Mary", 25));

        // 遍历
        for (Student student : students) {
            System.out.println(student);
        }

        HashMap<String, Student> hm = new HashMap<String, Student>();
        hm.put("Jack", new Student("Jack", 23));
        hm.put("Tom", new Student("Tom", 24));
        hm.put("Mary", new Student("Mary", 25));

        // 迭代器 EntrySet
        Set<Map.Entry<String, Student>> entries = hm.entrySet();
        Iterator<Map.Entry<String, Student>> iterator = entries.iterator();

        // 以下使用快捷键: 输入 itit,然后回车
        while (iterator.hasNext()) {
            Map.Entry<String, Student> next =  iterator.next();
            System.out.println(next.getKey() + "---" + next.getValue());
        }
    }
}

class Student {

    public String name;

    public int age;

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

泛型使用的注意事项和细节

  1. interface List<T>{}public class HashSet<E>{}.. 等等

    说明:

    T, E 只能是引用类型看看下面语句是否正确?

    List<Integer> list = new ArrayList<Integer>(); //OK

    List<int>list2 = new ArrayList<int>(); // 错误

  2. 在指定泛型具体类型后,可以传入该类型或者其子类类型

  3. 泛型使用形式

    List<Integer> list1 = new ArrayList<Integer>();

    实际开发中简写 List<Integer> list2 = new ArrayList<>();

  4. 如果我们这样写 List list3 = new ArrayList(); 默认给它的 泛型是 [<E> E就是 Object ]

    List<Object> list3 = new ArrayList<>()

练习题

题目要求

定义 Employee 类

  1. 该类包含: private 成员变量 name, sal, birthday,其中 birthday 为 MyDate 类的对象;
  2. 为每一个属性定义 getter, setter 方法;
  3. 重写 toString 方法输出 name, sal, birthday
  4. MyDate 类包含: private 成员变量 month, day, year; 幷为每一个属性定义 getter,。setter 方法
  5. 创建该类的 3 个对象,并把这些对象放入 ArrayList 集合中 ( ArrayList 需使用泛型来定义 ),对集合中的元素进行排序,并遍历输出
  6. 排序方式: 调用 ArrayList 的 sort 方法,传入 Comparator 对象【使用泛型】,先按照 name 排序,如果 name 相同,则按生日日期的先后排序。【即:定制排序】

代码实现

MyDate.java

package commonGenericity;

public class MyDate implements Comparable<MyDate> {
    private int month;
    private int day;
    private int year;

    public MyDate(int year, int month, int day) {
        this.month = month;
        this.day = day;
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    @Override
    public String toString() {
        return "MyDate{" +
                "month=" + month +
                ", day=" + day +
                ", year=" + year +
                '}';
    }


    @Override
    public int compareTo(MyDate o) {
        /**
         * 比较 birthday --- year
         * int yearMinus = year - o.getYear();
         * 等于 int year = this.year - o.getYear();
         */
        int yearMinus = year - o.getYear();
        if(yearMinus != 0) {
            return year;
        }

        // 如果 year 相同,比较 birthday --- month
        int monthMinus = month - o.getMonth();
        if(monthMinus != 0) {
            return month;
        }

        // 如果 year 和 month 都相同 只能返回 day
        return day - o.getDay();
    }
}

Employee.java

package commonGenericity;

public class Employee {
    private String name;
    private double sal;
    private MyDate birthday;

    public Employee(String name, double sal, MyDate birthday) {
        this.name = name;
        this.sal = sal;
        this.birthday = birthday;
    }

    public String getName() {
        return name;
    }

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

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }

    public MyDate getBirthday() {
        return birthday;
    }

    public void setBirthday(MyDate birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", birthday=" + birthday +
                '}';
    }
}

GenericExercise02.java

package commonGenericity;

import java.util.ArrayList;
import java.util.Comparator;

public class GenericExercise02 {
    public static void main(String[] args) {
        ArrayList<Employee> employees = new ArrayList<>();
        employees.add(new Employee("Jack", 20000, new MyDate(2000, 11, 30)));
        employees.add(new Employee("Tom", 20000, new MyDate(2001, 11, 30)));
        employees.add(new Employee("Tom", 20000, new MyDate(2000, 11, 30)));
        employees.add(new Employee("Aom", 20000, new MyDate(2000, 11, 30)));
        System.out.println(employees);
        System.out.println("========排序======");
        employees.sort(new Comparator<Employee>() {
            @Override
            public int compare(Employee emp1, Employee emp2) {
                // 先按照 name 排序,如果 name 相同,则按生日日期的先后排序。
                if(!(emp1 instanceof Employee && emp2 instanceof Employee)) {
                    System.out.println("类型不正确");
                    return 0;
                }
                // 比较 name
                int i = emp1.getName().compareTo(emp2.getName());
                // 如果 i 不等于 0 则 name 不相同,直接返回 i
                if(i != 0) {
                    return i;
                }


//                // 如果相同,比较 birthday --- year
//                int year = emp1.getBirthday().getYear() - emp2.getBirthday().getYear();
//                if(year != 0) {
//                    return year;
//                }
//
//                // 如果 year 相同,比较 birthday --- month
//                int month = emp1.getBirthday().getMonth() - emp2.getBirthday().getMonth();
//                if(month != 0) {
//                    return month;
//                }
//
//                // 如果 year 和 month 都相同 只能返回 day
//                return emp1.getBirthday().getDay() - emp2.getBirthday().getDay();

                // 将上面代码封装至 MyDate 类中,调用即可
                return emp1.getBirthday().compareTo(emp2.getBirthday());
            }
        });

        System.out.println("========排序======");
        System.out.println(employees);
    }
}