二、集合框架-泛型
public class GenericDemo {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("abc");
al.add("abc2");
al.add("abc3");
Iterator<String> it = al.iterator();
while(it.hasNext()) {
String str = it.next();
System.out.println(str);
}
}
}
1、概述:
jdk1.5出现的安全机制。
好处:
1、将运行时期的问题ClassCastException转到了编译时期。
2、避免了强制转换的麻烦。
<>:什么时候用?当操作的引用类型不确定的时候,就使用<>。将要操作的引用数据类型传入即可。
其实<>就是一个用于接收具体引用数据类型的参数范围。
2、泛型-擦除&补偿
泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。
运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称之为泛型的擦除。
为什么擦除?是为了兼容运行的类加载器。
泛型的补偿:在运行时,通过获取元素的类型进行转换。不用使用者再强制转换了。
3、泛型在集合中的应用
public class GenericDemo2 {
public static void main(String[] args) {
TreeSet<Person2> ts = new TreeSet<Person2>();
ts.add(new Person2("lisi8",21));
ts.add(new Person2("lisi2",23));
ts.add(new Person2("lisi",21));
ts.add(new Person2("lis0",20));
Iterator<Person2> it = ts.iterator();
while(it.hasNext()) {
Person2 p = it.next();
System.out.println(p.getName()+":"+p.getAge());
}
}
}
public class Person2 implements Comparable<Person2> {
private String name;
private int age;
public Person2() {
super();
}
public Person2(String name, int age) {
super();
this.name = name;
this.age = age;
}
public int compareTo(Person2 p){
int temp = this.age - p.getAge();
return temp==0?this.name.compareTo(p.getName()):temp;
}
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 CompareByname implements Comparator<Person2>{
public int compare(Person2 o1, Person2 o2) {
int temp = o1.getName().compareTo(o2.getName());
return temp == 0?o1.getAge() - o2.getAge():temp;
}
}
//按年龄排序,输出结果:
lis0:20
lisi:21
lisi8:21
lisi2:23
//按姓名排序,输出结果:
lis0:20
lisi:21
lisi2:23
lisi8:21
4、泛型类
在jdk1.5后,使用泛型来接收类中要操作的引用数据类型
什么时候用?当类中的操作的引用数据类型不确定的时候,就使用泛型来表示。
public class Student {
}
public class Worker {
}
public class Tool01<XX> {
private XX q;
public XX getObject() {
return q;
}
public void setObject(XX object) {
this.q = object;
}
}
public class GenericDemo3 {
public static void main(String[] args) {
Tool01<Student> tool = new Tool01<Student>();
tool.setObject(new Student());
Student stu = tool.getObject();
System.out.println(stu);
}
}
当tool.setObject(new Student());传递Worker对象时tool.setObject(new Worker());编译就会报错。
5、泛型方法
class Tool02<XX> {//泛型定义在类上
public void print(XX str) {
System.out.println("print:"+str);
}
/**
* 将泛型定义到方法上
*/
public <W> void show(W str) {
System.out.println("show:"+str);
}
/**
* 当定义静态方法时,不能访问类上定义的泛型。静态方法只能将泛型定义到方法上才能使用泛型。
*/
public static <Y> void output(Y str) {
System.out.println("output:"+str);
}
}
public class GenericDemo4 {
public static void main(String[] args) {
Tool02<String> tool = new Tool02<String>();
//print方法只能使用生成对象时指定的String类型
tool.print("abc");
//泛型定义到了tool方法上,可以传递任意类型对象,编译都不会报错
tool.show(new Integer(4));
tool.show("abc");
//静态方法的泛型只能定义到静态方法上可以传递任意类型对象
Tool02.output("abc");
Tool02.output(8);
}
}
6、泛型的接口
public class GenericDemo5 {
public static void main(String[] args) {
InterImpl in = new InterImpl();
in.show("abc");
InterImpl2<Integer> in2 = new InterImpl2<Integer>();
in2.show(5);
}
}
interface Inter<T>{
public void show(T t);
}
class InterImpl implements Inter<String>{
public void show(String str) {
System.out.println("show:"+str);
}
}
class InterImpl2<X> implements Inter<X>{
public void show(X x) {
System.out.println("show:"+x);
}
}
7、泛型限定(上限)
泛型的通配符:?
代表未知类型
public class GenericDemp6 {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("abc");
al.add("ddd");
ArrayList<String> al2 = new ArrayList<String>();
al.add("abc2");
al.add("ddd2");
printCollection(al);
printCollection(al2);
}
public static void printCollection(Collection<?> al) {
Iterator<?> it = al.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
public static <X> void printCollection2(Collection<X> al) {
Iterator<X> it = al.iterator();
while(it.hasNext()) {
X str = it.next();
System.out.println(str);
}
}
}
? extends E 限定只能传E或者E的子类
public class Student extends Person2{
public Student() {
super();
}
public Student(String name, int age) {
super(name, age);
}
public String toString() {
return "student:"+getName()+":"+getAge();
}
}
public class Worker extends Person2 {
public Worker() {
super();
}
public Worker(String name, int age) {
super(name, age);
}
public String toString() {
return "worker:"+getName()+":"+getAge();
}
}
public class GenericDemo7 {
public static void main(String[] args) {
ArrayList<Worker> al = new ArrayList<Worker>();
al.add(new Worker("worker01",30));
al.add(new Worker("worker02",32));
ArrayList<Student> al2 = new ArrayList<Student>();
al2.add(new Student("worker01",10));
al2.add(new Student("worker02",11));
printCollection(al);
printCollection(al2);
}
//限定只能传Person2的对象或者Person2的子类对象
private static void printCollection(ArrayList<? extends Person2> al) {
Iterator<? extends Person2> it = al.iterator();
while(it.hasNext()) {
System.out.println(it.next().toString());
}
}
}
8、泛型限定(下限)
? super E 限定只能传E或者E的父类
public class GenericDemo7 {
public static void main(String[] args) {
ArrayList<Person2> al = new ArrayList<Person2>();
al.add(new Person2("Person",30));
al.add(new Person2("Person",32));
ArrayList<Student> al2 = new ArrayList<Student>();
al2.add(new Student("worker01",10));
al2.add(new Student("worker02",11));
printCollection(al);
printCollection(al2);
}
//限定只能传Student的对象或者父类Person2的对象,而不能传Worker对象
private static void printCollection(ArrayList<? super Student> al) {
Iterator<? super Student> it = al.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
9、泛型限定-上限的体现
一般在存储元素时候都是用上限,因为这样取出的时都是按照上限类型来运算的。不会出现类型的安全隐患。
public class GenericDemo8 {
public static void main(String[] args) {
ArrayList<Person2> al = new ArrayList<Person2>();
al.add(new Person2("Person",30));
al.add(new Person2("Person",32));
ArrayList<Student> al2 = new ArrayList<Student>();
al2.add(new Student("studnet01",10));
al2.add(new Student("studnet02",11));
ArrayList<Worker> al3 = new ArrayList<Worker>();
al3.add(new Worker("worker01",20));
al3.add(new Worker("worker02",21));
al.addAll(al2);
al.addAll(al3);
}
}
class MyCollection<E>{
public void add(E e) {
}
public void addAll(MyCollection<? extends E> e){
}
}
10、泛型限定-下限的体现
通常对集合中的元素进行取出操作时,可以用下限。
public class GenericDemo9 {
public static void main(String[] args) {
TreeSet<Person2> al = new TreeSet<Person2>(new CompareByName2());
al.add(new Person2("aaa",30));
al.add(new Person2("bbb",32));
al.add(new Person2("ccc",32));
al.add(new Person2("ddd",34));
TreeSet<Student> al2 = new TreeSet<Student>();
al2.add(new Student("studnet01",10));
al2.add(new Student("studnet02",11));
al.addAll(al2);
Iterator<Person2> it = al.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
class CompareByName2 implements Comparator<Person2>{
@Override
public int compare(Person2 o1, Person2 o2) {
int temp = o1.getName().compareTo(o2.getName());
return temp == 0? o1.getAge() - o2.getAge():temp;
}
}