侧边栏壁纸
  • 累计撰写 53 篇文章
  • 累计收到 5 条评论

Chapter15_泛型

bbchen
2023-02-26 / 0 评论 / 41 阅读 / 正在检测是否收录...

泛型

泛型的理解和好处

  1. 编译时,检查添加元素的类型,提高了安全性
  2. 减少了类型转换的次数,提高效率
  3. 不再提示编译警告
package com.bbedu.generic.improve;

import java.util.ArrayList;

public class Generic02 {
    public static void main(String[] args) {

        // 这样写时,ArrayList<Dog> 表示存放到集合中的元素是 Dog 类型
        // 如果添加类型不满足要求,编译器会报错
        // 相当于加入约束
        // 在遍历时,可以直接取出 Dog 类型,而不是 Object
        ArrayList<Dog> arrayList = new ArrayList<Dog>();
        arrayList.add(new Dog("旺财", 10));
        arrayList.add(new Dog("发财", 5));
        arrayList.add(new Dog("大黄", 6));

        // 放入猫
        //arrayList.add(new Cat("招财猫", 3));

        for (Dog dog:arrayList) {
            System.out.println(dog.getName()+ "-" + dog.getAge());
        }
    }
}
class Dog {
    private String name;
    private int age;

    public Dog(String name, int age) {
        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;
    }
}

class Cat{
    private String name;
    private int age;

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

泛型的语法

声明

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

说明:

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

实例化

要在类名后面指定类型参数的值(类型),如:

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

细节

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

    说明:T,E只能是引用类型

  2. 在给泛型指定具体类型后,可以传入该类型或该类型的子类型
  3. 泛型的使用形式

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

    可简化为:// 编译器会进行类型推断,推荐这种写法:

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

  4. 如果是这样写:

    ArrayList arrayList = new ArrayList();

    等价于:

    ArrayList<Object> arrayList = new ArrayList<>();

练习 p560

image-20221014165805802

package com.bbedu.generic.exercise;

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

public class Exercise01 {
    public static void main(String[] args) {
        Employee jack = new Employee("Jack", 20000, new MyDate(1999, 1, 1));
        Employee jack2 = new Employee("Jack", 25000, new MyDate(1999, 1, 2));
        Employee mike = new Employee("Mike", 15000, new MyDate(2000, 2, 6));
        Employee sam = new Employee("Sam", 30000, new MyDate(1989, 10, 1));
        Employee tim = new Employee("Tim", 10000, new MyDate(2002, 4, 1));
        Employee tim2 = new Employee("Tim", 10000, new MyDate(2001, 4, 1));

        ArrayList<Employee> employees = new ArrayList<>();

        employees.add(sam);
        employees.add(jack2);
        employees.add(jack);
        employees.add(mike);
        employees.add(tim);
        employees.add(tim2);

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

        employees.sort(new Comparator<Employee>() {
            @Override
            public int compare(Employee o1, Employee o2) {
                if(!(o1 instanceof Employee && o2 instanceof Employee)){
                    System.out.println("类型不正确...");
                    return 0;
                }
                if(o1.getName().compareTo(o2.getName()) != 0){
                    return o1.getName().compareTo(o2.getName());
                }
                // 封装提升可维护性和复用性
                return o1.getBirthday().compareTo(o2.getBirthday());
            }
        });
        System.out.println("===排序后===");
        System.out.println(employees);
    }
}

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 +
                '}' + "\n";
    }
}

class MyDate implements Comparable<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 boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyDate myDate = (MyDate) o;
        return year == myDate.year && month == myDate.month && day == myDate.day;
    }

    @Override
    public int hashCode() {
        return Objects.hash(year, month, day);
    }

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

    @Override
    public int compareTo(MyDate o) {
        int yearMinus = year - o.getYear();
        if(yearMinus != 0){
            return yearMinus;
        }
        int monthMinus = month - o.month;
        if (monthMinus != 0) {
            return monthMinus;
        }
        return day - o.day;
    }
}

自定义泛型

泛型类

  1. 普通成员可以使用泛型(属性、方法)
  2. 使用泛型的数组,不能初始化
  3. 静态方法中不能使用类的泛型
  4. 泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)
  5. 如果在创建对象时,没有指定类型,默认为Object

泛型接口

  1. 接口中,静态成员不能使用泛型
  2. 泛型接口的类型,是在继承接口或者实现接口时实现的
  3. 没有指定类型时,默认为 Object

泛型方法

基本语法:

修饰符 <T, R> 返回方法 方法名(参数列表) {

}

  1. 泛型方法,可以定义在普通类中,也可以定义在泛型类中
  2. 当泛型方法被调用时,类型也会被确定
  3. 修饰符 返回方法 方法名(参数列表){}不是泛型方法,是使用了泛型的方法

泛型继承和通配符

  1. 泛型没有继承机制

    例如:

    List list = new ArrayList(); // 错误

  2. <?>: 支持任意类型的泛型
  3. <? extend AA> : 表示上限,可以接收 AA 或 AA 的子类
  4. <? super AA>: 表示下限,可以接收 AA 或 AA 的父类
  5. 本章作业

    image-20221019225010476

    JUnit

    1. 一个类有很多功能代码需要测试,为了测试,就需要写到 main 方法中
    2. 如果有多个功能代码测试,就需要来回注销,切换很麻烦
    3. 如果可以直接运行一个方法,就方便很多,并且可以给出相关信息 -> JUnit
    package com.bbedu.generic.homework;
    
    import org.junit.jupiter.api.Test;
    
    import java.util.*;
    
    public class Homework01 {
    
        @Test
        public void testList() {
            DAO<User> dao = new DAO<>();
            dao.save("001", new User(1, 10, "Jack"));
            dao.save("002", new User(2, 12, "Tom"));
            dao.save("003", new User(3, 14, "Mary"));
    
            System.out.println(dao.list());
    
            dao.update("003", new User(3, 23, "Milan"));
            System.out.println(dao.list());
    
            dao.delete("001");
            System.out.println(dao.list());
    
            System.out.println(dao.get("003"));
    
        }
    }
    
    class DAO<T> {
        private Map<String, T> map = new HashMap<>();
    
        public T get(String id) {
            return map.get(id);
        }
    
        public void update(String id, T entity) {
            map.put(id, entity);
        }
    
        public List<T> list() {
            List<T> list = new ArrayList<>();
    
            Set<String> strings = map.keySet();
            for (String string : strings) {
                list.add(get(string));
            }
            return list;
        }
    
        public void delete(String id) {
            map.remove(id);
        }
    
        public void save(String id, T entity) {
            map.put(id, entity);
        }
    }
    
    class User {
        private int id;
        private int age;
        private String name;
    
        public User(int id, int age, String name) {
            this.id = id;
            this.age = age;
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    0

    评论

    博主关闭了所有页面的评论