• 泛型「generic」讲解


    在这里插入图片描述

    🐋泛型语法

    1.1 泛型的引出

    1. 传统方法不能对加入到集合中的数据类型进行约束;
    2. 对集合遍历的时候需要进行类型转换,效率低;
    public class Generic01 {
    	public static void main(String[] args)ArrayList arrayList = new ArrayList();
    		arrayList.add(new Dog("scott",4));
    		arrayList.add(new Dog("jack",5));
    		arrayList.add(new Dog("mary",6));
    		for(Object o : arrayList) {
    			Dog dog = (Dog) o;//获取对象的名字
    			System.out.println(dog.getName());
    		}}
    class Dog {
    	private String name;
    	private int age;
    	public Dog(String name, int age) {
    		this.name = name;
    		this.age = age;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public int getAge() {
    		return age;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    1. 引出:new ArrayList(),表示存放到ArrayList 集合中的元素是Dog类型
    2. 优点
      • 如果编译器发现添加的类型不满足要求,就会报错,即编译时编译器会检查添加元素的类型,提高安全性;
      • 遍历时,可以直接取出Dog类型,而不是Object类型,减少了类型转换的次数;
    public class Generic01 {
    	public static void main(String[] args)ArrayList arrayList = new ArrayList<Dog>();
    		arrayList.add(new Dog("scott",4));
    		arrayList.add(new Dog("jack",5));
    		arrayList.add(new Dog("mary",6));
    		//arrayList.add(new Cat("招财猫",3));
    		for(Dog dog : arrayList) {
    			System.out.println(dog.getName());
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    不使用泛型:放入到ArrayList会先转成Object,在取出时,再转换成Dog;
    使用泛型:放入和取出时,不需要类型转换

    不使用泛型使用泛型
    放入到ArrayList会先转成Object,在取出时,再转换成Dog;放入和取出时,不需要类型转换;

    1.2 泛型介绍

    1. 泛型是可以表示数据类型的一种数据类型;
    2. 泛型又称为参数化类型,是jdk5.0出现的新特性,可以解决数据类型的安全性问题;
    3. 在类声明或者实例化的时候只需要指定需要的具体类型即可;
    4. Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException的异常;同时,代码更简洁、健壮。
    5. public class ArrayList ,相当于把Dog赋给了E,Dog->E
    6. 泛型的作用是: 可以在类声明时通过一个标识符表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型。
      - 参数的类型
      - 类中方法返回值的类型
      - 属性的类型
    泛型Generic
    参数的类型$1600
    类中方法返回值的类型$12
    属性的类型$1
    1. 在这里,E的类型一定要清楚的知道,可以通过getClass()方法得到;
    2. 注意:E具体的数据类型在定义Person对象时指定,即在编译期间就已确定类型;
      在这里插入图片描述

    1.3 泛型语法

    1. interface 接口 {} 和 class 类{}
    • 说明:
      • T、K、V不代表值,而是表示类型;
      • 任意字母都可以,常用T表示,T是Type的缩写
    1. 泛型的实例化:要在类名后面指定类型参数的值(类型),如:
      • (1)List stringList = new ArrayList();
      • (2)Interator iterator = dog.iterator();
        在这里插入图片描述
        在这里插入图片描述

    1.4 泛型使用细节

    1. interface List {}, public class HashSet {};
      T,E只能是引用类型,不能用基本数据类型;(Type argument cannot be of primitive type)
      在这里插入图片描述
    2. 在给泛型指定具体类型后,可以传入该类型或其子类类型;
      在这里插入图片描述
    3. 泛型的简写形式:省略构造器处的泛型表示,编译器会进行类型推断;
      List list = new ArrayList<>();
    4. 如果没有指定泛型,默认泛型是Object;
      Map hashMap = new HashMap();
      等价于
      Map hashMap = new HashMap<>();
      在这里插入图片描述
      在这里插入图片描述

    1.5 课堂练习

    定义Employee

    1. 该类包括: private成员变量name, sal, birthday, 其中birthdayMyDate 类的对象;

    2. 为每一个属性定义 getter, setter 方法;

    3. 重写 toString 方法输出 name, sal, birthday

    4. MyDate类包含: private成员变量month, day, year; 并为每一个属性定义 getter, setter 方法;

    5. 创建该类的 3 个对象, 并把这些对象放入到 ArrayList 集合中 (ArrayList 需使用泛型来定义), 对集合中的元素进行排序, 并遍历输出.

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


    代码
    MyDate类

    /*
    MyDate类包含: private成员变量month, day, year;
    并为每一个属性定义 getter, setter 方法;
    */
    public class MyDate {
        private Integer year;
        private Integer month;
        private Integer day;
    
        public MyDate(Integer year, Integer month, Integer day) {
            this.year = year;
            this.month = month;
            this.day = day;
        }
    
        //setter, getter方法, toString方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Employee类

    /*
    定义Employee类
    1) 该类包括: private成员变量name, sal, birthday, 其中birthday 为 MyDate 类的对象;
    2) 为每一个属性定义 getter, setter 方法;
    3) 重写 toString 方法输出 name, sal, birthday
    */
    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;
        }
        //setter, getter方法, toString方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    GenericExercise02

    /*
    创建该类的 3 个对象, 并把这些对象放入到 ArrayList 集合中
    (ArrayList 需使用泛型来定义), 对集合中的元素进行排序, 并遍历输出.
    
    排序方式: 调用 ArrayList 的 sort 方法, 传入 Comparator 对象 [使用泛型],
    先按照 name 排序, 如果 name 相同, 则按照生日日期的先后排序.[即:定制排序]
    */
    public class GenericExercise02 {
        public static void main(String[] args) {
    
            List<Employee> arrayList = new ArrayList<>();
            arrayList.add(new Employee("tom", 45000, new MyDate(1999, 12, 21)));
            arrayList.add(new Employee("tom", 35000, new MyDate(1999, 12, 25)));
            arrayList.add(new Employee("mary", 40000, new MyDate(1998, 5, 12)));
    
            System.out.println(arrayList);
    
            //对员工雇员进行排序
            arrayList.sort(new Comparator<Employee>() {
                @Override
                public int compare(Employee emp1, Employee emp2) {
                    //先按照 name 排序, 如果 name 相同, 则按照生日日期的先后排序.[即:定制排序]
                    //先对传入的参数进行验证
                    if (!(emp1 instanceof Employee && emp2 instanceof Employee)) {
                        return 0;
                    }
                    //比较名字
                    int i = emp1.getName().compareTo(emp2.getName());
                    if (i != 0) {
                        return i;
                    }
                    //下面是对MyDate类型的birthday对象的比较. 因此, 最好把这个比较, 放在MyDate类完成
                    //如果名字相同, 就比较birthday
                    int yearMinus = emp1.getBirthday().getYear() - emp2.getBirthday().getYear();
                    if (yearMinus != 0) {
                        return yearMinus;
                    }
                    //如果year相同, 就比较month
                    int monthMinus = emp1.getBirthday().getMonth() - emp2.getBirthday().getMonth();
                    if (monthMinus != 0) {
                        return monthMinus;
                    }
                    //如果month相同, 就比较day
                    int dayMinus = emp1.getBirthday().getDay() - emp2.getBirthday().getDay();
                    if (dayMinus != 0) {
                        return dayMinus;
                    }
                    return 0;
                }
    
            });
    
            System.out.println("===排序后的结果===");
            System.out.println(arrayList);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    改进后:封装后代码复用性更高
    MyDate 实现Comparable接口, 指定泛型, 实现compareTo方法

    public class MyDate implements Comparable<MyDate> {
        private Integer year;
        private Integer month;
        private Integer day;
        
        @Override
        public int compareTo(MyDate o) {把对year-month-day的比较放在这里
            int yearMinus = this.year - o.getYear();
            if (yearMinus != 0) {
                return yearMinus;
            }
            //如果year相同, 就比较month
            int monthMinus = this.month - o.getMonth();
            if (monthMinus != 0) {
                return monthMinus;
            }
            //如果month相同, 就比较day
            int dayMinus = this.day - o.getDay();
            if (dayMinus != 0) {
                return dayMinus;
            }
            return 0;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    GenericExercise02改进

    //下面是对MyDate类型的birthday对象的比较. 因此, 最好把这个比较, 放在MyDate类完成
    //如果名字相同, 就比较birthday
    //封装后, 将来可维护性和复用性, 就大大增强
    /*int yearMinus = emp1.getBirthday().getYear() - emp2.getBirthday().getYear();
    if (yearMinus != 0) {
        return yearMinus;
    }
    //如果year相同, 就比较month
    int monthMinus = emp1.getBirthday().getMonth() - emp2.getBirthday().getMonth();
    if (monthMinus != 0) {
        return monthMinus;
    }
    //如果month相同, 就比较day
    int dayMinus = emp1.getBirthday().getDay() - emp2.getBirthday().getDay();
    if (dayMinus != 0) {
        return dayMinus;
    }
    return 0;*/
    return emp1.getBirthday().compareTo(emp2.getBirthday());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Comparator实现定制排序👉传送门

    2.自定义泛型

    2.1自定义泛型-类

    1. 基本语法:class 类名 {} 可以有多个泛型
    2. 普通成员可以使用泛型(属性、方法);
    3. 使用泛型的数组不能初始化;
    4. 静态成员中不能使用类的泛型;
    5. 泛型类的类型,是在创建对象时确定的;(因为在创建对象时,需要指定类型)
    6. 如果在创建对象时,没有指定类型,默认为Object;
    public class CustomGeneric {
        public static void main(String[] args) {
            //T是Double,R是String,M是Integer
            Tiger<Double, String, Integer> tiger = new Tiger<>("john~~");
            tiger.setT(3.2);//OK
            System.out.println(tiger);
            Tiger tiger1 = new Tiger("john");
            //tiger.setT("yy");因为T是Object,"yy"是 Object子类,类型不对, 貌似字符串可以赋给Object类型
            
        }
    }
    //1.Tiger后面有泛型,所以我们把Tiger 称为自定义泛型类
    //2.T, R, M 泛型的标识符,一般是单个大写字母
    //3.泛型的标识符可以有多个
    //4.普通成员可以使用泛型 (属性、方法)
    //5.使用泛型的数组,不能初始化
    class Tiger<T, R, M> {
        String name;
        T t;//属性使用到泛型
        M m;
        R r;
    
        public Tiger(String name) {
            this.name = name;
        }
        //Type parameter 'T' cannot be instantiated directly
        //T[] ts = new T[8];类型不能确定,无法分配空间,因为数组在new的时候不能确定T的类型,就无法在内存开辟空间
        public Tiger(T t, M m, R r) {//构造器使用泛型
            this.t = t;
            this.m = m;
            this.r = r;
        }
        //因为静态是和类相关的,在类加载时,对象还没有创建
        //所以,如果静态方法和静态属性使用了泛型,JVM就无法完成初始化
        /*static R r2;
        public static void m1(M m) {//cannot be referenced from a static context
    
        }*/
    
        //方法使用泛型
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public T getT() {
            return t;
        }
    
        public void setT(T t) {
            this.t = t;
        }
    
        public M getM() {
            return m;
        }
    
        public void setM(M m) {
            this.m = m;
        }
    
        public R getR() {//返回类型可以使用泛型
            return r;
        }
    
        public void setR(R r) {//方法使用到泛型
            this.r = r;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    2.2自定义泛型-接口

    基本语法:interface 接口名 {}

    1. 接口中静态成员也不能使用泛型;(和泛型类规定一样)
    2. 泛型接口的类型,在继承接口或者实现接口时确定;
    3. 如果没有指定类型,默认为Object;(不规范,建议指定
    4. 方法参数列表中的泛型直接给值,类定义时的泛型给类型;
    5. /**
       * 泛型接口使用说明
       * 1.接口中,静态成员不能使用泛型
       * 2.泛型接口的类型是在继承接口或者实现接口时实现的
       */
      
      //1.在继承接口时,指定泛型接口的类型
      interface IA extends IUsb<String, Double> {
      
      }
      //当我们去实现IA接口时,因为IA在继承IUsb接口时,指定了U为String,R为Double
      // 因此在实现IUsb接口方法时,使用String替换U,Double替换R
      class AA implements IA {
      
          @Override
          public Double get(String s) {
              return null;
          }
      
          @Override
          public void hi(Double aDouble) {
      
          }
      
          @Override
          public void run(Double r1, Double r2, String u1, String u2) {
      
          }
      }
      //2.实现接口时,直接指定泛型接口的类型
      //给U指定了Integer, 给R指定了Float
      //所以当实现IUsb接口方法时,会使用Integer替换U,Float替换R
      class BB implements IUsb<Integer, Float> {
      
          @Override
          public Float get(Integer integer) {
              return null;
          }
      
          @Override
          public void hi(Float aFloat) {
      
          }
      
          @Override
          public void run(Float r1, Float r2, Integer u1, Integer u2) {
      
          }
      }
      
      //3.没有指定泛型,就默认为Object
      //等价于class CC implements IUsb {}, 但是不规范
      class CC implements IUsb {
          @Override
          public Object get(Object o) {
              return null;
          }
      
          @Override
          public void hi(Object o) {
      
          }
      
          @Override
          public void run(Object r1, Object r2, Object u1, Object u2) {
      
          }
      
      }
      interface IUsb<U, R> {//U=Integer, R=Float
          //接口中普通方法,可以使用泛型
          R get(U u);
      
          int n = 10;
          //U name = "3e";静态成员不能使用泛型
          void hi(R r);
      
          void run(R r1, R r2, U u1, U u2);
      
          //在jdk8以后,可以在接口中使用默认方法,在默认方法中可以使用泛型
          default R method(U u) {
              return null;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84

      2.3自定义泛型-方法

      基本语法:修饰符[空格] 返回类型 方法名(参数列表) {}

      1. 泛型方法,可以定义在普通类中,也可以定义在泛型类中;
      2. 当泛型方法被调用时,泛型类型就会确定,否则调用不起来;
      3. public void ear(E e) {},修饰符后面没有 , 那么eat方法就不是泛型方法,只是使用了泛型;
      4. 泛型方法可以使用类声明的泛型,也可以使用自己声明的泛型;
      public class CustomMethodGeneric_ {
          public static void main(String[] args) {
              Car car = new Car();
              //2. 当泛型方法被调用时,泛型类型就会确定,否则调用不起来;
              car.fly("宝马",1200);//当调用方法时,传入参数,编译器就会确定类型
              System.out.println("===========");
              car.fly(2.2,1200);//当调用方法时,传入参数,编译器就会确定类型
              System.out.println("===========");
              //T:Sring, R:ArrayList
              Fish<String, ArrayList> fish = new Fish<>();
              //K:Float
              fish.hello(new ArrayList(), 2.1f);
          }
      }
      //1.泛型方法,可以定义在普通类中
      class Car {//普通类
          public void run() {//普通方法
      
          }
          //说明:泛型方法
          //  就是泛型
          // 提供给fly方法使用的
          public <T, R> void fly(T t, R r) {//泛型方法
              System.out.println(t.getClass());//String
              System.out.println(r.getClass());//Integer
          }
      }
      //2.泛型方法,也可以定义在泛型类中
      class Fish<T, R> {//泛型类
          public void run() {//普通方法
      
          }
      
          public <U, M> void fly(U u, M m) {//泛型方法
      
          }
          //说明
          //  hi()方法不是一个泛型方法
          //  只是hi()方法使用了类声明的泛型
          public void hi(T e) {
      
          }
          //泛型方法,可以使用类声明的泛型,也可以使用自己声明的泛型
          public <K> void hello(R r, K k) {
              System.out.println(r.getClass());//ArrayList
              System.out.println(k.getClass());//Float
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48

      2.4练习题

      public class CustomMethodGenericExercise {
          public static void main(String[] args) {
              //T:String, R:Integer, M:Double
              Apple<String, Integer, Double> apple = new Apple<>();
              apple.fly(10);//泛型都是引用类型,所以10自动装箱,输出:Integer
              apple.fly(new Dog());//输出:Dog
          }
      }
      
      class Apple<T, R, M> {
          public <E> void fly(E e) {
              //.getClass().getName():显示包名+类名; 
              //.getClass().getSimpleName():只显示类名
              System.out.println(e.getClass().getSimpleName());
          }
          //public void eat(U u) {} //错误,U没有声明
          public <U> void eat(U u) {} //改正
          public void run(M m) {}
      
      }
      class Dog {}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21

      3.范型继承和通配符

      1. 泛型不具备继承性;
        List list = new ArrayList ();//这样写是错误的
      2. 通配符起到约束作用;
      3. 通配符作用
        List c表示可以接收任意范型类型
        List<? extends A> c表示可以接收A类或者A类的子类,规定泛型上限
        List c表示可以接收A类或者A类的父类(不限于直接父类),规定泛型下限
        @SuppressWarnings({"all"})
        public class GenericExtends {
            public static void main(String[] args) {
                //范型没有继承性
                //List list = new ArrayList();
                
                //举例说明下面三个方法的使用;
                List<Object> list1 = new ArrayList<>();
                List<String> list2 = new ArrayList<>();
                List<AA> list3 = new ArrayList<>();
                List<BB> list4 = new ArrayList<>();
                List<CC> list5 = new ArrayList<>();
                
                //1.如果是 List c, 可以接收任意的范型类型
                printCollection1(list1);
                printCollection1(list2);
                printCollection1(list3);
                printCollection1(list4);
                printCollection1(list5);
                
                //2.如果是 List c, 可以接收AA或者AA的子类
                //printCollection2(list1);
                //printCollection2(list2);
                printCollection2(list3);
                printCollection2(list4);
                printCollection2(list5);
        
                //3.如果是 List c, 可以接收AA,AA的父类但不限于直接父类
                printCollection3(list1);//正确
                //printCollection3(list2);
                printCollection3(list3);
                //printCollection3(list4);
                //printCollection3(list5);
            }
        
            public static void printCollection1(List<?> c) {
                for (Object object : c) {//通配符,取出时就是Object
                    System.out.println(object);
                }
            }
        
            public static void printCollection2(List<? extends AA> c) {
                for (AA object : c) {
                    System.out.println(object);
                }
            }
        
            //List 表示任意范型类型都可以接收
            //List 表示的是上限,可以接收 AA或AA的子类
            //List 表示的是下限,可以接收 AA或者AA的父类,不限于直接父类
            public static void printCollection3(List<? super AA> c) {
                for (Object object : c) {
                    System.out.println(object);
                }
            }
        }
        class AA {
        
        }
        class BB extends AA {
        
        }
        class CC extends BB {
        
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
        • 40
        • 41
        • 42
        • 43
        • 44
        • 45
        • 46
        • 47
        • 48
        • 49
        • 50
        • 51
        • 52
        • 53
        • 54
        • 55
        • 56
        • 57
        • 58
        • 59
        • 60
        • 61
        • 62
        • 63
        • 64
        • 65

        3.1JUnit单元测试框架

        shortcuts: Alt+Enter/option+Enter
        可以直接运行一个方法,JUnit测试框架;
        在这里插入图片描述

        public class JUnit_ {
            public static void main(String[] args) {
                //new JUnit_().m1();
                //new JUnit_().m2();
            }
            @Test
            public void m1() {
                System.out.println("m1()方法");
            }
            @Test
            public void m2() {
                System.out.println("m2()方法");
            }
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14

        3.2练习题

        public class Homework01 {
            public static void main(String[] args) {
        
            }
        
            @Test
            public void test() {
                //这里我们给泛型T指定的类型是User
                DAO<User> userDAO = new DAO<>();
                userDAO.save("No1", new User(1, 22));
                userDAO.save("No2", new User(2, 23));
                userDAO.save("No3", new User(3, 23));
                List<User> list = userDAO.list();
                userDAO.update("No3", new User(3, 18));
                list = userDAO.list();
                userDAO.delete("No3");
                list = userDAO.list();
                User user = userDAO.get("No2");
                System.out.println(list);
                System.out.println(user.getAge());
            }
        }
        
        class DAO<T> {
            private Map<String, T> map = new HashMap<>();
        
            public void save(String id, T entity) {
                map.put(id, entity);
            }
        
            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> arrayList = new ArrayList<>();
                Set<String> keySet = map.keySet();
                Iterator<String> iterator = keySet.iterator();
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    arrayList.add(get(key));
                }
                return arrayList;
            }
        
            public void delete(String id) {
                map.remove(id);
            }
        }
        class User {
            private int id;
            private int age;
        
            public User(int id, int age) {
                this.id = id;
                this.age = age;
            }
        
            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;
            }
        
            @Override
            public String toString() {
                return "\nUser{" +
                        "id=" + id +
                        ", age=" + age +
                        '}';
            }
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
        • 40
        • 41
        • 42
        • 43
        • 44
        • 45
        • 46
        • 47
        • 48
        • 49
        • 50
        • 51
        • 52
        • 53
        • 54
        • 55
        • 56
        • 57
        • 58
        • 59
        • 60
        • 61
        • 62
        • 63
        • 64
        • 65
        • 66
        • 67
        • 68
        • 69
        • 70
        • 71
        • 72
        • 73
        • 74
        • 75
        • 76
        • 77
        • 78
        • 79
        • 80
        • 81
        • 82
        • 83
        • 84
        • 85
        • 86
      4. 相关阅读:
        Spring Boot多线程详解
        vite创建vue3项目页面引用public下js文件失败解决
        pytorch深度学习实战24
        Redis 发布和订阅
        Linux安装与卸载Jenkins
        Java OutputStream.write()的功能简介说明
        小米云原生文件存储平台化实践:支撑 AI 训练、大模型、容器平台多项业务
        学位论文选题原则
        LeetCode(力扣)77. 组合Python
        平衡搜索树——B-树小记
      5. 原文地址:https://blog.csdn.net/qq_18817831/article/details/127856233