Java基础语法练习41(泛型以及自定义泛型)

目录

  一、泛型:用来表示数据类型的一种类型(在不知道定义为啥数据类型的时候用泛型来代替)

1.入门示例代码如下:

2.泛型的基本声明:

3.泛型的实例化:

二、自定义泛型类

三、自定义泛型接口

 四、自定义泛型方法

五、泛型的继承和通配符

 六、练习题


  一、泛型:用来表示数据类型的一种类型(在不知道定义为啥数据类型的时候用泛型来代替)

一句话:泛型是待定的数据类型

1.入门示例代码如下:

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

        //注意,特别强调:E具体的数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
        //当我定义Person类的时候不知道s为啥子类型,我就使用泛型进行定义
        Person person1=new Person("泛型"); //相当于使用String去替换了E
        System.out.println(person1.f());

        Person person2 = new Person(100);//相当于使用Integer去替换了E
        System.out.println(person2.f());

    }
}



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

class Person {

    E s;;//E 表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
    public Person(E s) {//E 也可以是参数类型
        this.s = s;
    }

    public E f() {//返回类型使用E
        return s;
    }
}

2.泛型的基本声明:

interface 接口{} 和 class 类 < K,V>{}
// 比如: List,ArrayList

1)其中,T,K,V 不代表值,而是表示类型。

2)任意字母都可以。常用 T 表示,是 Type 的缩写

3.泛型的实例化:

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

1)List strList = new ArrayList(); [举例说明]

2)Iterator iterator = customers.iterator();

泛型声明和实例化代码如下:

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

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

        //使用泛型方式给HashSet 放入3个学生对象
        HashSet students = new HashSet();
        students.add(new Student("jack", 18));
        students.add(new Student("tom", 28));
        students.add(new Student("mary", 19));

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

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


        //使用泛型方式给HashMap 放入3个学生对象
        //K-> String   V->Student
        HashMap hm = new HashMap();//约束了数据类型
        hm.put("milan", new Student("milan", 38));
        hm.put("smith", new Student("smith", 48));

        Set keyset = hm.keySet();
        for (Object key : keyset) {
            Student student = (Student) hm.get(key);
            System.out.println(student);
        }


    }
}


class Student {
    private String name;
    private int age;
    public Student(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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
        ", age=" + age +
                '}';
    }
}


4.测试题:Java基础语法练习41(泛型以及自定义泛型)_第1张图片

代码如下:

package Generic00001;

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

public class HomeWork001 {

    public static void main(String[] args) {


        ArrayList employees = new ArrayList<>();
        employees.add(new Employee("jack",200,new MyDate(2025,3,13)));
        employees.add(new Employee("rose",250,new MyDate(2025,3,14)));
        employees.add(new Employee("mary",300,new MyDate(2025,3,15)));
        System.out.println(employees);

        employees.sort(new Comparator() {
            @Override
            public int compare(Employee emp1, Employee emp2) {
                if(!(emp1 instanceof Employee && emp2 instanceof Employee)){
                    System.out.println("类型不正确..");
                    return 0;
                }

                //比较name
                int i = emp1.getName().compareTo(emp2.getName());
                if(i != 0) {
                    return i;
                }

                //比较year
                int yearMinus = emp1.getBirthday().getYear() - emp2.getBirthday().getYear();
                if(yearMinus != 0) {
                    return yearMinus;
                }

                //比较month
                int monthMinus = emp1.getBirthday().getMonth() - emp2.getBirthday().getMonth();
                if(monthMinus != 0) {
                    return monthMinus;
                }
                return emp1.getBirthday().getDay()-emp2.getBirthday().getDay();

            }
        });

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



    }
}

class Employee {
    private String name;
    private int sal;
    private MyDate birthday;

    public Employee(String name, int 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 int getSal() {
        return sal;
    }

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

    public MyDate getBirthday() {
        return birthday;
    }

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

    @Override
    public String toString() {
        return "\nEmployee{" +
                "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 "MyDate{" +
                "year=" + year +
                ", month=" + month +
                ", day=" + day +
                '}';
    }
}

二、自定义泛型类

  • 基本语法
    class 类名 { //... 表示可以有多个泛型
    成员
    }
  • 注意细节
  1. 普通成员可以使用泛型 (属性、方法)
  2. 使用泛型的数组,不能初始化
  3. 静态方法中不能使用类的泛型
  4. 泛型类的类型,是在创建对象时确定的 (因为创建对象时,需要指定确定类型)
  5. 如果在创建对象时,没有指定类型,默认为 Object

示例代码如下:

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



    }
}


//1. Tiger 后面泛型,所以我们把 Tiger 就称为自定义泛型类
//2, T, R, M 泛型的标识符, 一般是单个大写字母
//3. 泛型标识符可以有多个.
//4. 普通成员可以使用泛型 (属性、方法)
//5. 使用泛型的数组,不能初始化,因为数组在new 不能确定T的类型,就无法在内存开空间
//6. 静态方法中不能使用类的泛型,因为静态是和类相关的,在类加载时,对象还没有创建,类型还没确定
class Tiger {
    String name;
    R r; //属性使用到泛型
    M m;
    T t;

    public Tiger(String name, R r, M m, T t) {
        this.name = name;
        this.r = r;
        this.m = m;
        this.t = t;
    }
    public R getR() {     //返回的类型也可以是泛型
        return r;
    }

    //使用泛型的数组,不能初始化,因为数组在new 不能确定T的类型,就无法在内存开空间
    T[] ts;
    //T[] ts = new T[5];错误
}

三、自定义泛型接口

  • 基本语法
    interface 接口名 {
    }
  • 注意细节
  1. 接口中,静态成员也不能使用泛型 (这个和泛型类规定一样)
  2. 泛型接口的类型,在继承接口或者实现接口时确定
  3. 没有指定类型,默认为 Object

示例代码如下:

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



    }
}


//在继承接口 指定泛型接口的类型
interface IA extends IUsb {

}

//当我们去实现IA接口时,因为IA在继承IUsu 接口时,指定了U 为StringR为Double
//,在实现IUsu接口的方法时,使用String替换U, 是Double替换R
class AA implements IA {
    //当我们去实现IA接口时,因为IA在继承IUsu 接口时,指定了U 为StringR为Double
    //,在实现IUsu接口的方法时,使用String替换U, 是Double替换R
    @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) {
    }
}


//实现接口时,直接指定泛型接口的类型
//给 U 指定Integer 给 R 指定了 Float
//所以,当我们实现IUsb方法时,会使用Integer替换U, 使用Float替换R
class BB implements IUsb {
    @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) {
    }
}


//没有指定类型,默认为Object
//建议直接写成 IUsb
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 {
    int n = 10;

    //U name; 不能这样使用
    //普通方法中,可以使用接口泛型
    R get(U u);

    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. public void eat (E e) {},修饰符后没有 < T,R...> eat 方法不是泛型方法,而是使用了泛型

 示例代码如下:

import java.util.*;

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

        Car car = new Car();
        car.fly("宝马", 100);//当调用方法时,传入参数,编译器,就会确定类型
        car.fly(100.1, 100);


        //测试
        //T->String, R-> ArrayList
        Fish fish = new Fish<>();
        fish.hello(new ArrayList(), 11.3f);


    }
}

//1.泛型方法,可以定义在普通类中, 也可以定义在泛型类中
class Car {//普通类

    public void run() {//普通方法
    }
    public  void fly(T t, R r) {//泛型方法
        System.out.println(t.getClass());//String
        System.out.println(r.getClass());//Integer
    }


}

class Fish {//泛型类

    public void run() {//普通方法
    }

    public  void eat(U u, M m) {//泛型方法
    }

    //说明
    //1. 下面hi 方法不是泛型方法
    //2. 是 hi 方法使用了类声明的 泛型
    public void hi(T t) {           //因为没有<  >
    }

    public void hello(R r, K k) {
        //泛型方法,可以使用类声明的泛型,也可以使用自己声明泛型
        System.out.println(r.getClass());//ArrayList
        System.out.println(k.getClass());//Float
    }
}

五、泛型的继承和通配符

  1. 泛型不具备继承性
    List list = new ArrayList();// 错误

  2. : 支持任意泛型类型
  3. :支持A类以及A类的子类,规定了泛型的上限
  4. :支持A类以及A类的父类,不限于直接父类,规定了泛型的下限
  5. 示例代码如下:

    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Generic0001 {
        public static void main(String[] args) {
    
            Object o = new String("xx");
    
            //1.泛型没有继承性
            //List list = new ArrayList();
    
    
            List list1 = new ArrayList<>();
            List list2 = new ArrayList<>();
            List list3 = new ArrayList<>();
            List list4 = new ArrayList<>();
            List list5 = new ArrayList<>();
    
            //2.如果是 List c ,可以接受任意的泛型类型
            printCollection1(list1);
            printCollection1(list2);
            printCollection1(list3);
            printCollection1(list4);
            printCollection1(list5);
    
            //3.List c: 表示 上限,可以接受 AA或者AA子类
            //printCollection2(list1);//×
            //printCollection2(list2);//×
            printCollection2(list3);//√
            printCollection2(list4);//√
            printCollection2(list5);//√
    
    
            //4.List c: 支持 AA 类以及AA类的父类,不限于直接父类
            printCollection3(list1);//√
            //printCollection3(list2);//×
            printCollection3(list3);//√
            //printCollection3(list4);//×
            //printCollection3(list5);//×
    
    
        }
    
        //说明: List 表示 任意的泛型类型都可以接受
        public static void printCollection1(List c) {
            for (Object object : c) { // 通配符,取出时,就是Object
                System.out.println(object);
            }
        }
    
        // ? extends AA 表示 上限,可以接受 AA或者AA子类
        public static void printCollection2(List  c) {
            for (Object object : c) {
                System.out.println(object);
            }
        }
    
    
    
    
        // ? super 子类类名AA:支持AA类以及AA类的父类,不限于直接父类,
        //规定了泛型的下限
        public static void printCollection3(List c){
            for (Object object : c){
                System.out.println(object);
            }
        }
    
    
    
    
    
    }
    
    
    
    class AA{
    }
    class BB extends AA{
    }
    class CC extends BB {
    } 
      

     六、练习题

    Java基础语法练习41(泛型以及自定义泛型)_第2张图片

    实例代码如下:

    import java.util.*;
    
    public class HomeWork0002 {
        public static void main(String[] args) {
            DAO dao = new DAO();
            dao.save(String.valueOf(1),new User("jack",1,10));
            dao.save(String.valueOf(2),new User("mary",2,11));
            dao.save(String.valueOf(3),new User("rose",3,12));
    
            List list = dao.list();
            System.out.println(list);
    
        }
    }
    
    class DAO{
        private Map 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 list(){
    
            List list = new ArrayList<>();
            //遍历map
            Set keys = map.keySet();
            for(String key : keys){
                T entity = map.get(key);
                list.add(entity);
            }
    
            return list;
        }
        public void delete(String id){
            map.remove(id);
        }
    }
    
    class User{
        private String name;
        private int id;
        private int age;
        public User(String name, int id, int age){
            this.name = name;
            this.id = id;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            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;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", id=" + id +
                    ", age=" + age +
                    '}';
        }
    }
    

    你可能感兴趣的:(小白Java的成长,java,开发语言)