跳至主要內容

泛型

holic-x...大约 4 分钟

泛型

泛型引入

需求分析

​ 编写程序,在ArrayList中,添加3个Dog对象。Dog对象含有name和age,并输出name和age (要求使用getXxx())

​ 定义一个ArrayList,将小狗的信息装入,如果这个时候不小心混入一只小猫,则在处理过程中可能需要手动转化

​ 先使用传统的方法来解决->引出泛型

public class DogDemo{
    public static void main(String[] args) {
        // 传统方式引入
        ArrayList dogs = new ArrayList();
        dogs.add(new Dog("小黄",1));
        dogs.add(new Dog("大白",2));
        dogs.add(new Dog("小牛",3));

        // 混入一只cat
        dogs.add(new Cat("花小猫",1,"我是一只猫"));

        // 方式1:遍历数据(由于实体重写了toString,此处打印出来的是对象的toString,不需要额外转化)
        for (int i = 0; i < dogs.size(); i++) {
            System.out.println(dogs.get(i));
        }

        System.out.println("---------------- 分割线 ----------------");
        // 方式2:假设默认dogs里面都是Dog类型,并不知道混进去一只Cat
        for(Object dog : dogs){
            // 向下转型:Object=》Dog
            Dog d = (Dog) dog;
            System.out.println(d);
        }
    }
}


class Dog {

    public String name;
    public int age;

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

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

// 猫定义
class Cat {

    public String name;
    public int age;
    public String descr;

    public Cat(String name, int age, String descr) {
        this.name = name;
        this.age = age;
        this.descr = descr;
    }

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

​ 基于上述的内容分析,如果没有指定列表存储的数据类型,则可以加入任何Object,当数据列表中出现了预期之外的数据格式对象,则在遍历处理的时候就会出现问题(需要额外单独处理)

image-20240429160801503

​ 因此基于这种方式衍生两个问题:

  • 安全性:无法对加入到集合ArrayList的数据类型进行约束
  • 遍历的时候需要进行类型转换,如果集合数据量比较大则对效率有影响

​ 因此引入泛型进行约束,进而解决上面的问题

 				// 引用泛型
        ArrayList<Dog> dogs = new ArrayList<>();
        dogs.add(new Dog("小黄", 1));
        dogs.add(new Dog("大白", 2));
        dogs.add(new Dog("小牛", 3));

        // 混入一只cat 此时无法混入,因为dogs约束了添加元素必须为Dog对象
        // dogs.add(new Cat("花小猫", 1, "我是一只猫"));

​ 引入泛型具备的好处:

  • 编译时检查添加元素的类型,提高安全性
  • 减少类型转换的次数,提高效率(其分析如下)
    • 不引入泛型:Dog =》转化为Object加入列表=》取出时需要将Object转化为Dog
    • 引入泛型:数据存入和取出都是Dog(不需额外的数据类型转化处理)

​ 泛型的作用:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回类型、或者是参数类型

泛型语法

泛型声明

interface 接口<T>{}
class<K,V>{}

// 其中T、K、V不代表值,而是表示类型,可以使任意字母(一般用T,是Type缩写)

泛型实例化

List<String> strList = new ArrayList<String>();
Iterator<Customer> iterator = customers.iterator();

注意事项:

1. interface List<T>{}public class HashSet<E> {}..等等
说明: T, E只能是引用类型
  
List< Integer> list = new ArrayList< Integer> (); //OK
List<int> list2 = new ArrayList <int> 0)://错误

2. 在给泛型指定具体类型后,可以传入该类型或者其子类类型
  
3. 泛型使用形式
List<Integer> list1 = new ArrayList <Integer> ();
List< Integer> list2 = new ArrayList<> (); [说明:]


3. List list3 = new ArrayList(); # 默认给它的泛型是[<E> E就是Object 

泛型案例

定义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需使用泛型来定义),对集合中的元素进行排序,并遍历输出:

​ 排序方式:调用ArrayList 的sort方法,传入Comparator对象[使用泛型],先按照name排序,如果name相同,则按生日日期的先后排序。( 即:定制排序)

public class Employee {

    public static void main(String[] args) {
        List<Employee> employeeList = new ArrayList<Employee>();
        Employee e1 = new Employee("小C",1000,new MyDate(2004,03,23));
        Employee e2 = new Employee("小C",10000,new MyDate(1997,05,24));
        Employee e3 = new Employee("小A",8000,new MyDate(1968,12,16));
        employeeList.add(e1);
        employeeList.add(e2);
        employeeList.add(e3);

        Comparator comparator = new Comparator<Employee>() {

            @Override
            public int compare(Employee o1, Employee o2) {
                // 姓名相同比较年份
                if(o1.getName().equals(o2.getName())){
                   return o1.getBirthDay().toString().compareTo(o2.getBirthDay().toString());
                }else {
                    return o1.getName().compareTo(o2.getName());
                }
            }
        };
        employeeList.sort(comparator);
        for(Employee employee : employeeList){
            System.out.println(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 +
                '}';
    }
}


class MyDate{
    private int year;
    private int month;
    private int day;

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

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        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;
    }

    @Override
    public String toString() {
        return year + "-" + month + "-" + day;
    }
}
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3