Java基础之:泛型
Java基础之:泛型
在不使用泛型的情况下,在ArrayList 中,添加3个Dog。
Dog对象含有name 和 age, 并输出name 和 age (要求使用getXxx())。
package class_Generic;import java.util.ArrayList;public class ClassTest01 { @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) { ArrayList dog = new ArrayList(); dog.add(new Dog("旺财",2)); dog.add(new Dog("来福",4)); dog.add(new Dog("小黑",6)); for (Object obj : dog) { Dog temp = (Dog)obj; System.out.println(temp); } //使用泛型改进 //"<>"尖括号内应写入期望在ArrayList中存放的元素的类型或父类。 ArrayList<Dog> dogList = new ArrayList<Dog>(); dogList.add(new Dog("旺财",2)); dogList.add(new Dog("来福",4)); dogList.add(new Dog("小黑",6)); for (Dog d : dogList) { //在使用dogList内元素时,编译类型可以直接使用Dog System.out.println(d); } }}class Dog{ private String name; private Integer age; public Dog(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Dog [name=" + name + ", age=" + age + "]"; } }
总结:可以看到在不适用泛型的情况下,每次取出ArrayList中的对象都需要使用Object类型。需要向下转型才可以获得原来的数据类型Dog,而使用泛型指定之后让ArrayList中取出的元素直接就是Dog类型,但同时在加入元素时也只加入Dog类型及其子类的实例对象。而若不适用泛型,那么加入到ArrayList中的元素类型不受约束(不安全)。
泛型介绍
泛型又称参数化类型,是jdk5.0出现的新特性,解决数据类型的安全性问题。
Java 泛型可以保证如果程序在编译时没有发出警告,那么在运行时就不会出现ClassCastException异常。
在类声明时通过一个标识来表示类中某个属性的类型或是某个方法的返回值及参数类型。
泛型实例化
在类名后面指定参数类型的值(类型)。
package com.atguigu.generic;import java.util.ArrayList;import java.util.HashMap;public class Generic02 { public static void main(String[] args) { //给public class ArrayList<E> {} //解读 //给 E泛型 传入类型String //表我们可以给al放入的String, 或者是它的子类型 ArrayList<String> al = new ArrayList<String>(); al.add("tt"); al.add("hello"); //使用HashMap //public class HashMap<K,V> {} //解读 //1. K 指定为 String //2. V 指定为 Customer //3. 当我们使用hm 时,编译器,就会约束 加入 的 k 是String , v 就是 Customer HashMap<String, Customer> hm = new HashMap<String, Customer>(); hm.put("hello1", new Customer()); hm.put("100", new Person());//多态 HashMap<String, IMy> hm2 = new HashMap<String, IMy>(); hm2.put("200", new Tiger()); }}interface IMy { }class Tiger implements IMy { }class Customer { }class Person extends Customer { }
泛型使用
创建 3个学生对象。放入到 HashMap中,要求 Key 是 String, name, 使用泛型, Value 就是 学生对象。使用两种方式遍历
package class_Generic;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Map.Entry;import java.util.Set;public class ClassWork01 { public static void main(String[] args) { HashMap<String , Student> hashMap = new HashMap<>(); Student student1 = new Student("小范"); Student student2 = new Student("小黄"); Student student3 = new Student("小雨"); hashMap.put(student1.getName(),student1); hashMap.put(student2.getName(),student2); hashMap.put(student3.getName(),student3); Set<String> keySet = hashMap.keySet(); for (String string : keySet) { System.out.println("key:" + string + ",value:" + hashMap.get(string)); } System.out.println("==========================="); Set<Entry<String, Student>> entrySet = hashMap.entrySet(); Iterator<Entry<String, Student>> iterator = entrySet.iterator(); while(iterator.hasNext()) { Map.Entry<String, Student> node = iterator.next(); System.out.println("key:" + node.getKey() + ",value:" + node.getValue()); } }}class Student{ private String name; public Student(String name) { this.name = name; } @Override public String toString() { return "Student [name=" + name + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
泛型练习题
定义Employee类
1) 该类包含:private成员变量name,age,birthday,其中 birthday 为 MyDate 类的对象;
2) 为每一个属性定义 getter, setter 方法;
3) 重写 toString 方法输出 name, age, birthday
4) MyDate类包含: private成员变量month,day,year;并为每一个属性定义 getter, setter 方法;
5) 创建该类的 3 个对象,并把这些对象放入 ArrayList 集合中(ArrayList 需使用泛型来定义),对集合中的元素进行排序,并遍历输出:
排序方式: 调用ArrayList 的 sort 方法 , 传入 Comparator对象[使用泛型],先按照name,排序,如果name相同,则按生日日期的先后排序。【即:定制排序】
package class_Generic;import java.util.ArrayList;import java.util.Comparator;public class ClassWork02 { public static void main(String[] args) { Employee employee = new Employee("c小范", 20, new MyDate(2000, 3, 26)); Employee employee2 = new Employee("a小黄", 18, new MyDate(1999, 11, 25)); Employee employee3 = new Employee("b小雨", 20, new MyDate(2000, 4, 26)); ArrayList<Employee> list = new ArrayList<>(); // 推荐写法 list.add(employee); list.add(employee2); list.add(employee3); System.out.println("=============排序前============="); for (Employee em : list) { System.out.println(em); } list.sort(new Comparator<Employee>() { // 先按照name,排序,如果name相同,则按生日日期的先后排序。 @Override public int compare(Employee o1, Employee o2) { if (!(o1.getName().equals(o2.getName()))) { return o1.getName().compareTo(o2.getName()); } //未封装// MyDate temp1 = o1.getBirthday();// MyDate temp2 = o2.getBirthday();// if (temp1.equals(temp2)) {// return 0;// } else {// if (temp1.getYear() != temp2.getYear()) {// return temp1.getYear() - temp2.getYear();// }// if (temp1.getMonth() != temp2.getMonth()) {// return temp1.getMonth() - temp2.getMonth();// }// if (temp1.getDay() != temp2.getDay()) {// return temp1.getDay() - temp2.getDay();// }// return 0;// } //封装方式 return o1.getBirthday().compareTo(o2.getBirthday()); } }); System.out.println("=============排序后============="); for (Employee em : list) { System.out.println(em); } }}class Employee { private String name; private int age; private MyDate birthday; public Employee(String name, int age, MyDate birthday) { super(); this.name = name; this.age = age; this.birthday = birthday; } @Override public String toString() { return "Employee [name=" + name + ", age=" + age + ", birthday=" + birthday + "]"; } 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; }public MyDate getBirthday() {return birthday; }public void setBirthday(MyDate birthday) {this.birthday = birthday; }@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Employee other = (Employee) obj;if (name == null) {if (other.name != null)return false; } else if (!name.equals(other.name))return false;return true; }}class MyDate implements Comparable<MyDate>{//使用泛型指定比较MyDate类型对象private int year;private int month;private int day;public MyDate(int year, int month, int day) {super();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 setMouth(int month) {this.month = month; }public int getDay() {return day; }public void setDay(int day) {this.day = day; }@Overridepublic String toString() {return year + "-" + month + "-" + day; }@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;MyDate other = (MyDate) obj;if (day != other.day)return false;if (month != other.month)return false;if (year != other.year)return false;return true; }@Overridepublic int compareTo(MyDate o) {//比较if(year != o.year) {return year - o.year; }if(month != o.month) {return month - o.month; }return day - o.day; }}
程序输出:
=============排序前=============
Employee [name=c小范, age=20, birthday=2000-3-26]
Employee [name=a小黄, age=18, birthday=1999-11-25]
Employee [name=b小雨, age=20, birthday=2000-4-26]
=============排序后=============
Employee [name=a小黄, age=18, birthday=1999-11-25]
Employee [name=b小雨, age=20, birthday=2000-4-26]
Employee [name=c小范, age=20, birthday=2000-3-26]