ToB企服应用市场:ToB评测及商务社交产业平台

标题: day28--Java泛型01 [打印本页]

作者: 水军大提督    时间: 2022-9-16 17:22
标题: day28--Java泛型01
Java泛型01

1.泛型的理解和好处

看一个需求:
先用传统的方法来解决--->引出泛型
传统的方法:
  1. package li.generic;
  2. import java.util.ArrayList;
  3. @SuppressWarnings("all")
  4. public class Introduce_ {
  5.     public static void main(String[] args) {
  6.         
  7.         //用传统的方法来解决
  8.         ArrayList arrayList = new ArrayList();
  9.         arrayList.add(new Dog("旺财",10));
  10.         arrayList.add(new Dog("发财",1));
  11.         arrayList.add(new Dog("小黄",5));
  12.         
  13.         for (Object o:arrayList) {
  14.             //向下转型
  15.             Dog dog = (Dog) o;
  16.             System.out.println(dog.getName()+"-"+dog.getAge());
  17.         }
  18.     }
  19. }
  20. class Dog {
  21.     private String name;
  22.     private int age;
  23.     public Dog(String name, int age) {
  24.         this.name = name;
  25.         this.age = age;
  26.     }
  27.     public String getName() {
  28.         return name;
  29.     }
  30.     public void setName(String name) {
  31.         this.name = name;
  32.     }
  33.     public int getAge() {
  34.         return age;
  35.     }
  36.     public void setAge(int age) {
  37.         this.age = age;
  38.     }
  39. }
复制代码
  1. //假设,我们的程序员不小心添加了一只猫
  2. arrayList.add(new Cat("招财猫",8));
复制代码
那么 在使用增强for循环输出的时候向下转型时就会抛出异常:类型转换错误

使用传统方法问题的分析:
使用泛型来解决问题:
  1. package li.generic;
  2. import java.util.ArrayList;
  3. @SuppressWarnings("all")
  4. public class Introduce_ {
  5.     public static void main(String[] args) {
  6.         //使用泛型
  7.         // 1. 当我们这样写的时候:ArrayList<Dog>  表示集合ArrayList中的元素是Dog类型
  8.         // 2. 如果编译器发现添加的类型不满足要求,就会报错
  9.         // 3.在遍历的时候,可以直接取出Dog类型而不是Object
  10.         ArrayList<Dog> arrayList = new ArrayList<Dog>();
  11.         arrayList.add(new Dog("旺财",10));
  12.         arrayList.add(new Dog("发财",1));
  13.         arrayList.add(new Dog("小黄",5));
  14.         //假设,我们的程序员不小心添加了一只猫,就会报错
  15.         // arrayList.add(new Cat("招财猫",8));
  16.         System.out.println("====使用泛型====");
  17.         for (Dog dog:arrayList) {
  18.             System.out.println(dog.getName()+"-"+dog.getAge());
  19.         }
  20.     }
  21. }
  22. class Dog {
  23.     private String name;
  24.     private int age;
  25.     public Dog(String name, int age) {
  26.         this.name = name;
  27.         this.age = age;
  28.     }
  29.     public String getName() {
  30.         return name;
  31.     }
  32.     public void setName(String name) {
  33.         this.name = name;
  34.     }
  35.     public int getAge() {
  36.         return age;
  37.     }
  38.     public void setAge(int age) {
  39.         this.age = age;
  40.     }
  41. }
  42. class Cat {
  43.     private String name;
  44.     private int age;
  45.     public Cat(String name, int age) {
  46.         this.name = name;
  47.         this.age = age;
  48.     }
  49.     public String getName() {
  50.         return name;
  51.     }
  52.     public void setName(String name) {
  53.         this.name = name;
  54.     }
  55.     public int getAge() {
  56.         return age;
  57.     }
  58.     public void setAge(int age) {
  59.         this.age = age;
  60.     }
  61. }
复制代码
  1. package li.generic;
  2. import java.util.ArrayList;
  3. @SuppressWarnings("all")
  4. public class Introduce_ {
  5.     public static void main(String[] args) {
  6.         //使用泛型
  7.         // 1. 当我们这样写的时候:ArrayList<Dog>  表示集合ArrayList中的元素是Dog类型
  8.         // 2. 如果编译器发现添加的类型不满足要求,就会报错
  9.         // 3.在遍历的时候,可以直接取出Dog类型,而不是Object
  10.         ArrayList<Dog> arrayList = new ArrayList<Dog>();
  11.         arrayList.add(new Dog("旺财",10));
  12.         arrayList.add(new Dog("发财",1));
  13.         arrayList.add(new Dog("小黄",5));
  14.         //假设,我们的程序员不小心添加了一只猫,就会报错
  15.         // arrayList.add(new Cat("招财猫",8));
  16.         System.out.println("====使用泛型====");
  17.         for (Dog dog:arrayList) {
  18.             System.out.println(dog.getName()+"-"+dog.getAge());
  19.         }
  20.     }
  21. }
  22. class Dog {
  23.     private String name;
  24.     private int age;
  25.     public Dog(String name, int age) {
  26.         this.name = name;
  27.         this.age = age;
  28.     }
  29.     public String getName() {
  30.         return name;
  31.     }
  32.     public void setName(String name) {
  33.         this.name = name;
  34.     }
  35.     public int getAge() {
  36.         return age;
  37.     }
  38.     public void setAge(int age) {
  39.         this.age = age;
  40.     }
  41. }
  42. class Cat {
  43.     private String name;
  44.     private int age;
  45.     public Cat(String name, int age) {
  46.         this.name = name;
  47.         this.age = age;
  48.     }
  49.     public String getName() {
  50.         return name;
  51.     }
  52.     public void setName(String name) {
  53.         this.name = name;
  54.     }
  55.     public int getAge() {
  56.         return age;
  57.     }
  58.     public void setAge(int age) {
  59.         this.age = age;
  60.     }
  61. }
复制代码
泛型的好处:
2.泛型介绍

泛型是一种可以表示数据类型的 数据类型
如下图:public class ArrayList{}  E 称为泛型

泛(广泛)型(类型)===>integer,String,Dog,……
例子:
  1. package li.generic;
  2. public class Generic03 {
  3.     public static void main(String[] args) {
  4.         Person<String> person = new Person<String>("jack");
  5.         person.showCalss();//class java.lang.String
  6.         /*
  7.        可以这样理解:上面的Person类变为了
  8.        class Person{
  9.             String s;
  10.              public Person(String s) {
  11.                 this.s = s;
  12.             }
  13.             public String f() {
  14.              return s;
  15.             }
  16.         }
  17.         */
  18.         Person<Integer> person1 = new Person<Integer>(100);
  19.         person1.showCalss();//class java.lang.Integer
  20.         /*  可以这样理解:上面的Person类变为了
  21.        class Person{
  22.             Integer s;
  23.              public Person(Integer s) {
  24.                 this.s = s;
  25.             }
  26.             public Integer f() {
  27.              return s;
  28.             }
  29.         }
  30.         */
  31.     }
  32. }
  33. class Person<E> {
  34.     E s; // 用 E表示 s的数据类型,该数据类型在定义 Person对象的时候指定,即在编译期间,就确定 E是什么类型
  35.     public Person(E s) {//E也可以是参数类型
  36.         this.s = s;
  37.     }
  38.     public E f() {//返回类型使用E
  39.         return s;
  40.     }
  41.     public void showCalss(){
  42.         System.out.println(s.getClass());//显示s的运行类型
  43.     }
  44. }
复制代码
注意:E的数据类型在定义 Person 对象的时候指定,即在编译期间,就确定E是什么类型
泛型是一种可以表示数据类型的 数据类型
3.泛型的语法

3.1泛型的声明

interface 接口{}  和class 类{}//比如:List、ArrayList
说明:
1)其中,T,K,V不代表值,而是表示类型
2)任意字母都可以。常用T表示,是Type的缩写
3.2泛型的实例化

要在类名后面指定类型参数的值(类型),如:
(1)List strList = new ArrayList() ;
(2)Iterator iterator = customer.iterator();
3.3泛型使用举例

例子:泛型使用举例:
练习:
练习:
  1. package li.generic;
  2. import java.util.*;
  3. public class GenericExercise {
  4.     public static void main(String[] args) {
  5.         //使用泛型的方法给HashSet放入三个学生对象
  6.         HashSet<Student> students = new HashSet<Student>();
  7.         students.add(new Student("jack", 18));
  8.         students.add(new Student("marry", 17));
  9.         students.add(new Student("link", 123));
  10.         //使用HashSet的增强for
  11.         System.out.println("===使用HashSet的增强for===");
  12.         for (Student student : students) {
  13.             System.out.println(student);
  14.         }
  15.         //使用泛型的方法给HashMap放入三个学生对象
  16.         HashMap<String, Student> hm = new HashMap<String, Student>();
  17.         hm.put("jack", new Student("jack", 18));
  18.         hm.put("lucy", new Student("lucy", 28));
  19.         hm.put("olin", new Student("olin", 16));
  20.         //迭代器 EntrySet
  21.         System.out.println("===迭代器 EntrySet===");
  22.         Set<Map.Entry<String,Student>> entries = hm.entrySet();
  23.        Iterator<Map.Entry<String,Student>> iterator1 = entries.iterator();
  24.         while (iterator1.hasNext()) {
  25.             Map.Entry<String, Student> next =  iterator1.next();
  26.             System.out.println(next.getKey()+"-"+next.getValue());
  27.         }
  28.     }
  29. }
  30. class Student {
  31.     private String name;
  32.     private int age;
  33.     public Student(String name, int age) {
  34.         this.name = name;
  35.         this.age = age;
  36.     }
  37.     public String getName() {
  38.         return name;
  39.     }
  40.     public void setName(String name) {
  41.         this.name = name;
  42.     }
  43.     public int getAge() {
  44.         return age;
  45.     }
  46.     public void setAge(int age) {
  47.         this.age = age;
  48.     }
  49.     @Override
  50.     public String toString() {
  51.         return "Student{" +
  52.                 "name='" + name + '\'' +
  53.                 ", age=" + age +
  54.                 '}';
  55.     }
  56. }
复制代码
3.4泛型使用的注意事项和细节

例子:
  1. package li.generic;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class GenericDetail {
  5.     public static void main(String[] args) {
  6.         //1.给泛型指向的数据类型要求是引用类型,不能是基本数据类型
  7.         List<Integer> list = new ArrayList<Integer>();//ok
  8.         //List<int> list2 = new ArrayList<int>();错误
  9.         //2.因为 E指定了A类型,构造器传入了 new A()
  10.         Pig<A> aPig = new Pig<A>(new A());//将A类型赋给泛型E,说明Pig构造器可以接收的是A类型的对象
  11.         //在指定泛型具体类型后,可以传入该类型或者其子类类型
  12.         Pig<A> aPig2 = new Pig<A>(new B());
  13.         aPig.showClass();//class li.generic.A
  14.         aPig2.showClass();//class li.generic.B
  15.         // 3.泛型的使用形式
  16.         //在实际的开发中,我们往往简写,编译器会进行类型推断,推荐使用下面的写法
  17.         ArrayList<Integer> list1 = new ArrayList<>();
  18.         
  19.     }
  20. }
  21. class A{}
  22. class B extends A{}
  23. class Pig<E>{
  24.     E e;
  25.     public Pig(E e) {
  26.         this.e = e;
  27.     }
  28.     public void showClass(){
  29.         System.out.println(e.getClass());//运行类型
  30.     }
  31. }
复制代码
4.泛型课堂练习

定义Employee类
练习:
  1. package li.generic;
  2. import java.util.ArrayList;
  3. import java.util.Comparator;
  4. public class GenericHomework {
  5.     public static void main(String[] args) {
  6.         ArrayList<Employee> employees = new ArrayList<>();
  7.         employees.add(new Employee("tom", 20000, new MyDate(1980, 12, 11)));
  8.         employees.add(new Employee("jack", 12000, new MyDate(2001, 12, 12)));
  9.         employees.add(new Employee("tom", 50000, new MyDate(1980, 12, 10)));
  10.         employees.sort(new Comparator<Employee>() {
  11.             @Override
  12.             public int compare(Employee o1, Employee o2) {
  13.                
  14. //                //比较name
  15. //                int i = o1.getName().compareTo(o2.getName());
  16. //                if (i != 0) {
  17. //                    return i;
  18. //                }
  19. //                //如果name相同,就比较birthday-year
  20. //                int yearMinus = o1.getBirthday().getYear()-o2.getBirthday().getYear();
  21. //                if (yearMinus !=0) {
  22. //                    return yearMinus;
  23. //                }
  24. //                //如果year相同,就比较month
  25. //                int monthMinus = o1.getBirthday().getMonth()-o2.getBirthday().getMonth();
  26. //                if (monthMinus !=0) {
  27. //                    return monthMinus;
  28. //                }
  29. //                //如果month相同,就比较mday
  30. //                return o1.getBirthday().getDay()-o2.getBirthday().getDay();
  31.                 //比较name
  32.                 int i = o1.getName().compareTo(o2.getName());
  33.                 if (i != 0) {
  34.                     return i;
  35.                 }
  36.                
  37.                 //下面是对birthday的比较,因此,我们最好把日期的比较放到MyDate类完成
  38.                 //封装后的维护性和复用性更好
  39.                return o1.getBirthday().compareTo(o2.getBirthday());
  40.             }
  41.         });
  42.         for (Employee e : employees) {
  43.             System.out.println(e);
  44.         }
  45.     }
  46. }
  47. class Employee {
  48.     private String name;
  49.     private int sal;
  50.     private MyDate birthday;
  51.     public Employee(String name, int sal, MyDate birthday) {
  52.         this.name = name;
  53.         this.sal = sal;
  54.         this.birthday = birthday;
  55.     }
  56.     public String getName() {
  57.         return name;
  58.     }
  59.     public void setName(String name) {
  60.         this.name = name;
  61.     }
  62.     public int getSal() {
  63.         return sal;
  64.     }
  65.     public void setSal(int sal) {
  66.         this.sal = sal;
  67.     }
  68.     public MyDate getBirthday() {
  69.         return birthday;
  70.     }
  71.     public void setBirthday(MyDate birthday) {
  72.         this.birthday = birthday;
  73.     }
  74.     @Override
  75.     public String toString() {
  76.         return "Employee{" +
  77.                 "name='" + name + '\'' +
  78.                 ", sal=" + sal +
  79.                 ", birthday=" + birthday +
  80.                 '}';
  81.     }
  82. }
  83. class MyDate implements Comparable<MyDate>{
  84.     private int year;
  85.     private int month;
  86.     private int day;
  87.     public MyDate(int year, int month, int day) {
  88.         this.year = year;
  89.         this.month = month;
  90.         this.day = day;
  91.     }
  92.     public int getYear() {
  93.         return year;
  94.     }
  95.     public void setYear(int year) {
  96.         this.year = year;
  97.     }
  98.     public int getMonth() {
  99.         return month;
  100.     }
  101.     public void setMonth(int month) {
  102.         this.month = month;
  103.     }
  104.     public int getDay() {
  105.         return day;
  106.     }
  107.     public void setDay(int day) {
  108.         this.day = day;
  109.     }
  110.     @Override
  111.     public String toString() {
  112.         return "MyDate{" +
  113.                 "year='" + year + '\'' +
  114.                 ", month='" + month + '\'' +
  115.                 ", day='" + day + '\'' +
  116.                 '}';
  117.     }
  118.     @Override
  119.     public int compareTo(MyDate o) {//把 年 月 日 的比较挪到这里
  120.         //如果name相同,就比较birthday-year
  121.         int yearMinus = year-o.getYear();
  122.         if (yearMinus !=0) {
  123.             return yearMinus;
  124.         }
  125.         //如果year相同,就比较month
  126.         int monthMinus = month-o.getMonth();
  127.         if (monthMinus !=0) {
  128.             return monthMinus;
  129.         }
  130.         //如果month相同,就比较mday
  131.         return day-o.getDay();
  132.     }
  133. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4