目录
一、泛型的介绍
二、泛型的语法
2.1 泛型的声明
2.2 泛型的实例化
2.3 泛型使用举例
2.3 泛型使用的注意事项和细节
2.4 泛型课堂练习题
2.5 自定义泛型类
2.6 自定义泛型接口
2.7 自定义泛型方法
三、泛型的继承和通配符说明
interface List
说明:
要在类名后面指定类型参数的值(类型)。如:
1) List
2) Iterator
举例说明,泛型在 HashSet, TreeSet, HashMap 的使用情况, 看老师演示
import java.util.HashMap; import java.util.HashSet; import java.util.Set;
public class GenericDemo03 { public static void main(String[] args) { // TODO Auto-generated method stub // 举例说明,泛型在 HashSet, TreeSet, HashMap 的使用情况, 看老师演示
HashSet Student student1 = new Student("jack", 1); Student student2 = new Student("tom", 10); Student student3 = new Student("smith", 4); hashSet.add(student1); hashSet.add(student2); hashSet.add(student3);
//遍历 for (Student student : hashSet) { System.out.println(student); }
// 双列集合 //public class HashMap HashMap hashMap.put("100", student1); hashMap.put("200", student2); hashMap.put("300", student3);
//遍历 Set for (String key : keySet) { Student student = hashMap.get(key); System.out.println("s=" + student); } }
}
class Student { public String name; public int age;
public Student(String name, int age) { super(); this.name = name; this.age = age; }
@Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; }
}
|
1) interface List
说明:T, E 只能是引用类型
看看下面语句是否正确?:
List
List
2) 泛型使用的形式
List
List
定义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 com.atguigu.generic;
import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator;
public class GenericExercise01 {
public static void main(String[] args) { // TODO Auto-generated method stub ArrayList MyDate myDate1 = new MyDate(2000,11,11); MyDate myDate2 = new MyDate(2000,11,10); MyDate myDate3 = new MyDate(2000,11,1);
Employee employee1 = new Employee("jack", 10, myDate1); Employee employee2 = new Employee("jack", 20, myDate2); Employee employee3 = new Employee("jack", 30, myDate3);
arrayList.add(employee1); arrayList.add(employee2); arrayList.add(employee3);
//迭代器 Iterator while(iterator.hasNext()) { Employee employee = iterator.next(); System.out.println(employee); }
//定制排序. arrayList.sort(new Comparator
@Override public int compare(Employee o1, Employee o2) { //先看名字 int compareTo1 = o1.getName().compareTo(o2.getName()); if(compareTo1 !=0) {//比较有结果 return compareTo1; } else { //比较 生日. return o1.getBirthday().compareTo(o2.getBirthday()); } } }); System.out.println("排序=" + arrayList);
}
} /* * 定义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相同,则按生日日期的先后排序。【即:定制排序】
*/ 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; } 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; } @Override public String toString() { return "Employee [name=" + name + ", age=" + age + ", birthday=" + birthday + "]\n"; }
}
class MyDate implements Comparable 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 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 + "]"; } @Override public int compareTo(MyDate o) { //想到... //比较年 int compare1 = year - o.year; if(compare1 != 0) { return compare1; } else { //比较月 int compare2 = month - o.month; if(compare2 != 0) { return compare2; } else { return day - o.day; } } }
} |
class 类名
成员
}
注意细节
1) 普通成员可以使用泛型
2) 使用泛型的数组,不能初始化
3) 静态成员中不能使用泛型
4) 泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)
5) 如果在创建对象时,没有指定类型,默认为Object
下面举例说明自定义泛型的使用, 看老师演示.
package com.atguigu.generic;
public class CustomGeneric {
public static void main(String[] args) {
//使用自定义泛型 //解读 //1. 当创建对象时, T 就是 String // R 就是 Integer // M 就是 Double MyGeneric
//变化 myGeneric.setM(100.3); myGeneric.setR(100); myGeneric.setT("hello");
System.out.println(myGeneric.getT());
// T 就是 Book // R 就是 Float // M 就是 String MyGeneric
//如果在创建对象时,没有指定类型,默认为Object MyGeneric
}
}
class Book {
}
//自定义的泛型 class MyGeneric String name; R r; // 普通成员属性,可以使用泛型
// 普通成员方法,可以使用泛型 public R getR() { return r; }
public void setR(R r) { this.r = r; }
public M getM() { return m; }
public void setM(M m) { this.m = m; }
M m; T t; // 不允许泛型数组开辟长度或初始化, 因为数组在开空间时,大小需要明确,而T 不能明确空间大小 //T[] ts = new T[9];
// 不允许静态成员使用泛型, 因为 静态成员是在加载类的时候,就完成,而我们的T是在创建对象时,才确定 // 因为,不能通过 // static T m; // public static void method(T t){ // // } public static void show() { }
public T getT() { return t; }
public void setT(T t) { this.t = t; }
@Override public String toString() { return "MyGeneric [name=" + name + "]"; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public MyGeneric(String name) { super(); this.name = name; } }
|
interface 接口名
}
1) 接口中,静态成员也不能使用泛型
2) 泛型接口的类型, 在接口被扩展时(即:被继承或者实现) 会确定
3) 没有指定类型,默认为Object
代码演示
public class InterfaceGeneric { public static void main(String[] args) { // TODO Auto-generated method stub AA aa = new AA(); aa.app(1); aa.consume(12, 20, "hello", "jack"); } }
interface MyInter // 普通方法中,可以使用接口泛型 R get(T u); void app(R r); void consume(R r1, R r2, T u1, T u2);
// 在jdk8 中,可以再接口中,使用默认方法 default R method(T u) { return null; } }
// 类与接口是实现, 传入了类型, 使用到泛型 class AA implements MyInter @Override public Integer get(String u) { // TODO Auto-generated method stub return null; } @Override public void app(Integer r) { // TODO Auto-generated method stub } @Override public void consume(Integer r1, Integer r2, String u1, String u2) { // TODO Auto-generated method stub } }
// 接口和接口之间是继承, 指定了类型 // 再去继承 MyInter2时,就会体现泛型 interface MyInter2 extends MyInter
}
class BB implements MyInter2 { @Override public Double get(Double u) { // TODO Auto-generated method stub return null; } @Override public void app(Double r) { // TODO Auto-generated method stub } @Override public void consume(Double r1, Double r2, Double u1, Double u2) { // TODO Auto-generated method stub } } }
|
修饰符
}
1) 泛型不具备继承性
2) > :支持任意泛型类型
3) extends A>:支持A类以及A类的子类,规定了泛型的上限
4) super A>: 支持A类以及A类的父类,不限于直接父类,规定了泛型的下限
代码演示
package com.atguigu.generic;
import java.util.ArrayList; import java.util.List;
public class GenericPattern {
public static void main(String[] args) { // TODO Auto-generated method stub ArrayList ArrayList ArrayList ArrayList ArrayList
// 如果是 List> 表示都能接受. printCollection1(al3); printCollection1(al1); printCollection1(al2); printCollection1(al4); printCollection1(al5);
// List extends AA> 是可以接受 AA 或者 AA的子类型 // AA 是上限 . // printCollection2(al1); // printCollection2(al2); printCollection2(al3);// ok printCollection2(al4);// ok printCollection2(al5);// ok
// printCollection3(al1);// ok Object 是 AA父类 // printCollection3(al2);//error String 和AA 没有关系 // printCollection3(al3);// ok AA // printCollection3(al4);// error BB 是AA的子类 // printCollection3(al5);// error CC 是 AA 的子类
}
// ? super 子类类名A:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限 public static void printCollection3(List super AA> c) { for (Object object : c) { System.out.println(object); } }
// 解读 // 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 extends AA> c) { for (Object object : c) { System.out.println(object); } }
}
class AA { // 超类 }
class BB extends AA {// 父类 }
class CC extends BB {// 子类 }
|