泛型基本说明
- 使用传统方法的问题分析
- 泛型的好处
- 编译时,检查添加元素的类型,提高了安全性
- 减少了类型转换的次数,提高效率
- 不在提示编译警告
-
package com.hspedu.generic.improve;import java.util.ArrayList;/* @author 韩顺平* @version 1.0*/ @SuppressWarnings({"all"}) public class Generic02 {public static void main(String[] args) {//使用传统的方法来解决===> 使用泛型//老韩解读//1. 当我们 ArrayList<Dog> 表示存放到 ArrayList 集合中的元素是Dog类型 (细节后面说...)//2. 如果编译器发现添加的类型,不满足要求,就会报错//3. 在遍历的时候,可以直接取出 Dog 类型而不是 Object//4. public class ArrayList<E> {} E称为泛型,那么 Dog->EArrayList<Dog> arrayList = new ArrayList<Dog>();arrayList.add(new Dog("旺财", 10));arrayList.add(new Dog("发财", 1));arrayList.add(new Dog("小黄", 5));//假如我们的程序员,不小心,添加了一只猫//arrayList.add(new Cat("招财猫", 8));System.out.println("===使用泛型====");for (Dog dog : arrayList) {System.out.println(dog.getName() + "-" + dog.getAge());}} }/* 1.请编写程序,在ArrayList 中,添加3个Dog对象 2.Dog对象含有name 和 age, 并输出name 和 age (要求使用getXxx()) 3.老师使用泛型来完成代码*/ 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 { //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;} }
-
泛型说明
-
package com.hspedu.generic;import java.util.List;/* @author 韩顺平* @version 1.0*/ public class Generic03 {public static void main(String[] args) {//注意,特别强调: E具体的数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型Person<String> person = new Person<String>("韩顺平教育");person.show(); //String/*你可以这样理解,上面的Person类class Person {String s ;//E表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型public Person(String s) {//E也可以是参数类型this.s = s;}public String f() {//返回类型使用Ereturn s;}}*/Person<Integer> person2 = new Person<Integer>(100);person2.show();//Integer/*class Person {Integer s ;//E表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型public Person(Integer s) {//E也可以是参数类型this.s = s;}public Integer f() {//返回类型使用Ereturn s;}}*/} }//泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型, // 或者是某个方法的返回值的类型,或者是参数类型class Person<E> {E s ;//E表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型public Person(E s) {//E也可以是参数类型this.s = s;}public E f() {//返回类型使用Ereturn s;}public void show() {System.out.println(s.getClass());//显示s的运行类型} }
E就代表你这个集合里的元素是什么类型的元素,而且必须是引用类型,不能是基本数据类型
-
泛型又称参数化类型,是JDK5.0出现的新特性,解决数据类型的安全性问题
-
在类声明或实例化时只要指定好需要的具体的类型即可
-
泛型的作用:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型
-
-
泛型的语法
-
interface 接口<E>{}和class 类<K,V>{}
-
字母不代表值,而是数据类型
-
-
应用实例
-
package com.jshedu.generic;import java.util.*;/* @author Mr.jia* @version 1.0* 创建 3个学生对象* 放到HashSet中学生对象,要求Key是String name,Value就是学生对象*/public class Generic02 {public static void main(String[] args) {HashSet<Student> students = new HashSet<Student>();students.add(new Student("jack",28));students.add(new Student("tom",23));students.add(new Student("lucy",26));//遍历for (Student o :students) {System.out.println(o);}//使用泛型方式给HashMap放入3个学生,这个是两个参数的,//HashMap<String, Student>,传参时也要两个HashMap<String, Student> ssh = new HashMap<String, Student>();//迭代器里面的参数为什么会自动填充String,Student//定义HashMap的时候已经把k和V指定了ssh.put("tom",new Student("tom",58));ssh.put("king",new Student("king",48));ssh.put("rose",new Student("rose",38));//迭代器EntrySetSet<Map.Entry<String, Student>> entries = ssh.entrySet();Iterator<Map.Entry<String, Student>> iterator = entries.iterator();while (iterator.hasNext()) {Map.Entry<String, Student> next = iterator.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;}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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\\'' +", age=" + age +'}';} }
注意自动填充是从HashMap的K和V来的
-
-
泛型注意事项
-
E不能为基本数据类型,要求为引用类型
-
在给泛型指定具体类型后,可以传入该类型或者其子类类型
-
如果这样写泛型默认是Object 。ArrayList arrayList = new ArrayList();
-
等价ArrayList<Object> objects = new ArrayList<>();
-
-
package com.jshedu.generic;import java.util.ArrayList; import java.util.Comparator;/* @author Mr.jia* @version 1.0*/public class Homework01 {public static void main(String[] args) {ArrayList<Employee> employees = new ArrayList<>();employees.add(new Employee("jack",12222,new MyDate(2023,4,17)));employees.add(new Employee("tomwaew",10000,new MyDate(2023,5,17)));employees.add(new Employee("tomwewewe",22222,new MyDate(2023,6,17)));System.out.println(employees);employees.sort(new Comparator<Employee>() {@Overridepublic int compare(Employee o1, Employee o2) {//先按照name排序,如果name相同,则按照生日日期//先对传入的参数进行验证if(!(o1 instanceof Employee && o2 instanceof Employee)){System.out.println("类型不正确...");return 0;}//比较name,这里是o1对象调用compareTo方法//name是比较的字母谁在前,不是name的长度int i = o1.getName().compareTo(o2.getName());if(i !=0){return i;}//如果name相同,就比较birthday-yearint yearMinus = o1.getBirthday().getYear()-o2.getBirthday().getYear();if(yearMinus != 0){return yearMinus;}//如果year相同,就比较monthint monthMinus = o1.getBirthday().getMonth()-o2.getBirthday().getMonth();if(monthMinus != 0){return monthMinus;}//year和month都相同return o1.getBirthday().getDay()-o2.getBirthday().getDay();}});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;}@Overridepublic String toString() {return "\\nEmployee{" +"name='" + name + '\\'' +", sal=" + sal +", birthday=" + birthday +'}';} } class MyDate{private int month;private int day;private int year;public MyDate(int year, int month, int day) {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;}@Overridepublic String toString() {return "MyDate{" +"month=" + month +", day=" + day +", year=" + year +'}';} }
Arrays.sort()底层代码,可以把年月日的比较封装到MyDate,MyDate接口实现Comparable<MyDate>,然后重写Comparable接口下的compareTo(MyDate o)方法
-