java学习笔记 - 第15章:泛型

第15章:泛型

  • 总体内容
  • 泛型generic
    • 泛型的理解和好处
    • 泛型介绍
    • 泛型语法
    • 泛型应用实例
    • 泛型细节
    • 课堂练习
  • 自定义泛型
    • 自定义泛型类
    • 自定义泛型接口
    • 自定义泛型方法
  • 泛型继承和通配符
  • 引申:JUnit使用(单元测试框架)
    • 为什么需要JUnit
    • 基本介绍
    • 演示使用步骤
  • 本章练习

总体内容

java学习笔记 - 第15章:泛型_第1张图片

泛型generic

泛型的理解和好处

java学习笔记 - 第15章:泛型_第2张图片
传统方法
java学习笔记 - 第15章:泛型_第3张图片
会出现的问题
java学习笔记 - 第15章:泛型_第4张图片
java学习笔记 - 第15章:泛型_第5张图片
使用泛型解决上面出现的问题(数据约束+可以直接遍历,无需向下转型)
java学习笔记 - 第15章:泛型_第6张图片
在这里插入图片描述
泛型的好处
java学习笔记 - 第15章:泛型_第7张图片

泛型介绍

泛型的理解
int a = 1/2/100–>这个a就表示1/2/100,a表示了不同的整数值
E <–Integer/Double/String,这个E表示了不同的数据类型,如果把Integer赋值给E,则E就是Integer类型

java学习笔记 - 第15章:泛型_第8张图片
在类声明时,通过一个泛型的标识表示数据类型,然后在实例化该类时,再指定泛型具体的数据类型, 若指定后,有类型不匹配的现象,则在编译时就会显示错误

java学习笔记 - 第15章:泛型_第9张图片

泛型语法

java学习笔记 - 第15章:泛型_第10张图片

泛型应用实例

java学习笔记 - 第15章:泛型_第11张图片

import java.util.*;

public class Excise {
    public static void main(String[] args) {
        Student wpz = new Student("王胖子", 21);
        Student gsz = new Student("高瘦子", 23);
        Student xy = new Student("小艺", 22);
        HashSet<Student> studentHashSet = new HashSet<>();
        studentHashSet.add(wpz);
        studentHashSet.add(gsz);
        studentHashSet.add(xy);
        //public class HashMap K->String V->Student
        HashMap<String, Student> studentHashMap = new HashMap<String, Student>();
        studentHashMap.put("王胖子", wpz);
        studentHashMap.put("高瘦子", gsz);
        studentHashMap.put("小艺", xy);
        System.out.println("===HashSet增强for===");
        for (Student student : studentHashSet) {
            System.out.println(student);
        }
        System.out.println("===HashMap迭代器===");
        //public class HashMap K->String V->Student
        // public Set> entrySet() 
        // public final Iterator> iterator()
        Set<Map.Entry<String, Student>> entries = studentHashMap.entrySet();
        Iterator<Map.Entry<String, Student>> iterator1 = entries.iterator();
        while (iterator1.hasNext()) {
            Map.Entry<String, Student> next = iterator1.next();
            System.out.println(next.getKey() + "-" + next.getValue());
        }
    }
}

class Student {
    private String name;
    private int age;

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

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

泛型细节

java学习笔记 - 第15章:泛型_第12张图片

课堂练习

java学习笔记 - 第15章:泛型_第13张图片

本题重点是比较

  • 使用ArrayList中的sort(),传入一个Comparator匿名类,自定义实现compare()方法,Comparator和compare()中用到了泛型(规定的数据类型进行比较)
  • 先按name比较,使用String的compareTo()方法
  • 若name相同,则比较生日的前后,比较生日写到了MyDate类中
  • 让MyDate实现Comparable,再实现compareTo()方法,comparable和compareTo()中也用到了泛型(规定的数据类型进行比较)
import java.util.ArrayList;
import java.util.Comparator;

public class Excise {
    public static void main(String[] args) {
        ArrayList<Employee> employees = new ArrayList<>();
        employees.add(new Employee("高瘦子", 3000, new MyDate(3, 3, 1999)));
        employees.add(new Employee("王胖", 2000, new MyDate(1, 2, 2001)));
        employees.add(new Employee("王胖", 1000, new MyDate(1, 1, 2001)));
        //对集合中元素排序并输出(sort定制排序)
        employees.sort(new Comparator<Employee>() {
            @Override
            public int compare(Employee o1, Employee o2) {
                //先按照name排序,若name相同,则按照生日日期先后顺序排序
                int nameRes = o1.getName().compareTo(o2.getName());
                if (nameRes != 0) {
                    //compareTo()返回的是int,所以直接返回nameRes即可
                    return nameRes;
                }
                //下面是对birthday的比较,所以最好把这个比较放在MyDate类中完成
                //封装后,可维护性和复用性大大增强
                return o1.getBirthday().compareTo(o2.getBirthday());
            }
        });
        for (Employee e : employees) {
            System.out.println(e);
        }

    }
}

//实现Comparable接口 实现compareTo()方法,比较的数据类型是MyDate
class MyDate implements Comparable<MyDate> {
    private int month;
    private int day;
    private int year;

    public MyDate(int month, int day, int year) {
        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) {//把对year-month-day的比较放在这里
        int yearMinus = year - o.getYear();
        if (yearMinus != 0) {
            return yearMinus;
        }
        int monthMinus = month - o.getMonth();
        if (monthMinus != 0) {
            return monthMinus;
        }
        //不需要再像前面那样写了,比较到最后,直接返回day相减的值即可
        return day - o.getDay();
    }
}

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;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", 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;
    }
}

输出结果:
java学习笔记 - 第15章:泛型_第14张图片

自定义泛型

自定义泛型类

java学习笔记 - 第15章:泛型_第15张图片

  • class Tiger ,T,R,M是泛型的标识符,Tiger称为自定义泛型类
  • 使用泛型的数据,不能初始化,因为数组在new时,不确定T的类型,无法在内存中开辟空间
    T[] ts = new T[8];//这里T是泛型标识符,这是错误的
  • 静态方法或静态属性中不能使用泛型,因为静态是和类相关的,在类加载时,对象还没创建,所以如果静态…使用了泛型,那jvm无法完成初始化

自定义泛型接口

java学习笔记 - 第15章:泛型_第16张图片

  • 注意:接口中属性是静态的且必须初始化,方法默认为 public abstract(所以经常只写返回值 方法名(参数)),接口中方法使用default时必须有方法体
  • 接口中静态成员不能使用泛型:
    U name;//这是不行的,因为接口中属性都是静态的,且必须初始化
  • 继承接口或实现接口时,确定泛型的具体类型:在实现接口的方法时,具体泛型的数据类型替换掉了泛型标识
    java学习笔记 - 第15章:泛型_第17张图片
    默认为Object,但是建议写上
    在这里插入图片描述

java学习笔记 - 第15章:泛型_第18张图片

自定义泛型方法

java学习笔记 - 第15章:泛型_第19张图片

  • 定义和使用(当泛型方法被调用时,类型被确定)
    java学习笔记 - 第15章:泛型_第20张图片

泛型继承和通配符

java学习笔记 - 第15章:泛型_第21张图片

import java.util.ArrayList;
import java.util.List;

public class Excise {
    public static void main(String[] args) {
        //举例说明三种方法的使用
        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<>();
        //演示第一种方法,剩下的不演示了
        printCollection1(list1);
        printCollection1(list2);
        printCollection1(list3);
        printCollection1(list4);
        printCollection1(list5);
    }

    //说明:List 表示List集合中可以放 任意类型的数据
    public static void printCollection1(List<?> c) {
        for (Object o : c) {
            System.out.println(o);
        }
    }

    //说明:List 表示List集合中可以放 AA或者AA的子类
    public static void printCollection2(List<? extends AA> c) {
        for (Object o : c) {
            System.out.println(o);
        }
    }

    //说明:List 表示List集合中可以放 AA或者AA的父类
    public static void printCollection3(List<? super AA> c) {
        for (Object o : c) {
            System.out.println(o);
        }
    }
}

//AA,BB,CC的继承关系
class AA { }

class BB extends AA { }

class CC extends BB { }

引申:JUnit使用(单元测试框架)

为什么需要JUnit

java学习笔记 - 第15章:泛型_第22张图片

基本介绍

在这里插入图片描述

演示使用步骤

java学习笔记 - 第15章:泛型_第23张图片
java学习笔记 - 第15章:泛型_第24张图片
java学习笔记 - 第15章:泛型_第25张图片
java学习笔记 - 第15章:泛型_第26张图片
java学习笔记 - 第15章:泛型_第27张图片

本章练习

java学习笔记 - 第15章:泛型_第28张图片

import org.junit.Test;

import java.util.*;

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

    }
	//使用JUnit单元测试框架
    @Test
    public void testList() {
        DAO<User> userDAO = new DAO<>();
        userDAO.save("001", new User(1, 21, "王胖子"));
        userDAO.get("001");
        userDAO.update("001", new User(2, 22, "小艺"));
        System.out.println(userDAO.list());
//        userDAO.delete("002");
    }
}

//DAO自定义泛型类
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) {//根据id获取
        return map.get(id);
    }

    public void update(String id, T entity) {//修改
        map.put(id, entity);
    }

    public List<T> list() {//获取所有value
        //不能进行强制类型转换,会报错
        //但是可以把结果全部装到list中
        List<T> values = new ArrayList<>();
        values.addAll(map.values());
        return values;
        //第二种-用get方法获取value加入到arrayList中
//        ArrayList list = new ArrayList<>();//存放values
//        Set keySet = map.keySet();//取出所有的key
//        for (String key :keySet) {
//            //这里用到了前面定义的方法get()或者写成map.get(key)也行
//            list.add(get(key));//用key得到对应的value 放入list中
//        }
//        return list;
    }

    public void delete(String id) {//根据id删除
        map.remove(id);
    }
}

//User类
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 + '\'' +
                '}';
    }
}

输出:
java学习笔记 - 第15章:泛型_第29张图片

你可能感兴趣的:(java基础学习笔记,java,学习,单元测试)