- 使用传统方法的问题分析
- 不能对加入到集合ArrayList中的数据类型进行约束(不安全)
- 遍历的时候,需要进行类型转换,如果集合中的数据量较大,对效率有影响。
- 泛型的好处
- 编译时,检查添加元素的类型,提高了安全性
- 减少了类型转换的次数,提高效率
- 不在提示编译警告
-
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->E ArrayList<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() {//返回类型使用E return 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() {//返回类型使用E return s; } } */ } } //泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型, // 或者是某个方法的返回值的类型,或者是参数类型 class Person<E> { E s ;//E表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型 public Person(E s) {//E也可以是参数类型 this.s = s; } public E f() {//返回类型使用E return 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)); //迭代器EntrySet Set<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; } @Override public 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>() { @Override public 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-year int yearMinus = o1.getBirthday().getYear()-o2.getBirthday().getYear(); if(yearMinus != 0){ return yearMinus; } //如果year相同,就比较month int 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; } @Override public 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; } @Override public String toString() { return "MyDate{" + "month=" + month + ", day=" + day + ", year=" + year + '}'; } }
Arrays.sort()底层代码,可以把年月日的比较封装到MyDate,MyDate接口实现Comparable<MyDate>,然后重写Comparable接口下的compareTo(MyDate o)方法
-
文章来源:https://www.toymoban.com/news/detail-417361.html
文章来源地址https://www.toymoban.com/news/detail-417361.html
到了这里,关于泛型基本说明的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!