首页 > 代码库 > JAVA学习第四十二课 — 泛型(二)—泛型接口&&通配符应用

JAVA学习第四十二课 — 泛型(二)—泛型接口&&通配符应用

一、泛型接口

interface Inter<T>{
	public void show(T t);
}
class InterImple implements Inter<String>{//知道是字符串类型
	public void show(String str){
		System.out.println("show "+str);
	}
}
class InterImple_2<Q> implements Inter<Q>{//不知道是什么类型,使用的时候才知道
	public void show(Q q){
		System.out.println("InterImple_2.show()+"+q);
	}
}
public class Main 
{
	public static void main(String[] args) {
		InterImple in = new InterImple();
		in.show("sf");
		
		InterImple_2<Integer> in2 = new InterImple_2<Integer>();
		in2.show(2);
	}
}


二、泛型限定 


泛型的通配符,通俗的说就是不管什么类型,都用一个符号表示T,E,X,?...
其中通配符?和通配符T区别不大

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

public class Main 
{
	public static void main(String[] args) {
		ArrayList<String> al = new ArrayList<String>();
		al.add("ads");
		al.add("sfdf");
		show(al);
		ArrayList<Integer> a3 = new ArrayList<Integer>();
		a3.add(5);
		a3.add(6);
		show(a3);
		HashSet<Integer> al2 =  new HashSet<Integer>();
		al2.add(1);
		al2.add(2);
		show(al2);
	}
	//如果单纯是打印,通配符用?即可
	public static void show(Collection<?> al)
	{
		Iterator<?> it = al.iterator();
		Iterator<?> it = al.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
	}
	//如果需要返回继续操作
//	public static <T> T show(Collection<T> al) {
//		Iterator<T> iterator = al.iterator();
//		T t = iterator.next();
//		return t;
//	}
}

关于迭代器

/*Iterator<T> it = al.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}*/
		//java5.0 以后用了更为优雅的for each循环,与iterator表示同样的循环
		for(T x : al){
			System.out.println(x);
		}

简洁明了
通配符第一种演示:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Main 
{
	public static void main(String[] args) {
		ArrayList<Worker> al = new ArrayList<Worker>();
		al.add(new Worker("abc",12));
		al.add(new Worker("dgh",11));
	
		show(al);
		ArrayList<Student> a3 = new ArrayList<Student>();
		a3.add(new Student("ASD",156));
		a3.add(new Student("AFDFD",16));

		show(a3);
	}
	//如果只想打印Man的子类
	//Collection<Man>不对,Collection<Man> = new ArrayList<Student>();左右类型不匹配
	//所以在泛型声明,就可以采用继承的方式
	public static void show(Collection<? extends Man> al)
	{//
		Iterator<? extends Man> it = al.iterator();
		while(it.hasNext()){
			Man man = it.next();
			System.out.println(man);
		}
	}//等价于
	public static <T extends Man> void  show1(Collection<T> al)
	{//
		for(T xT : al)
			System.out.println(xT);
	}
}

所以泛型存的限定有两种:
上限:?extends E,?只能就收E类型或E的子类

下限:? super E,接受E类型或E的父类


三、上限的体现:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Main 
{
	public static void main(String[] args) {
		
	ArrayList<Man> al1 = new ArrayList<Man>();
		al1.add(new Man("ABC",12));
		al1.add(new Man("DGH",11));
		
		ArrayList<Worker> al2 = new ArrayList<Worker>();
		al2.add(new Worker("abc",12));
		al2.add(new Worker("dgh",11));
		
		ArrayList<Student> al3 = new ArrayList<Student>();
		al3.add(new Student("abc",12));
		al3.add(new Student("dgh",11));
		
		al1.addAll(al2);//一般存元素的时候,都是上限,因为这样取出都是按照上限类型来运算的,不会出现类型安全隐患 
		
		System.out.println(al1.size());
	}
}

详细看API文档,addAll方法 : addAll(? extends E),可以存储E及E的所有子类


四、下限的体现:

通常对集合中元素进行取出动作时,可以用下限
也就是不论存什么类型(只要是当前父类的子类),都可以用父类型接收

import java.util.Comparator;
import java.util.TreeSet;
import java.util.Iterator;
class ComparaName implements Comparator<Man>{
//按姓名排序
	public int compare(Man o1, Man o2) {
		// TODO Auto-generated method stub
		int t = o1.getName().compareTo(o2.getName());	
		return t==0?o1.getAge()-o2.getAge():t;
	}
}
public class Main 
{
	public static void main(String[] args) {
		
	TreeSet<Man> al1 = new TreeSet<Man>(new ComparaName());
		al1.add(new Man("ABC",12));
		al1.add(new Man("DGH",11));
		
		TreeSet<Worker> al2 = new TreeSet<Worker>();
		al2.add(new Worker("abc",12));
		al2.add(new Worker("dgh",11));
		
		TreeSet<Student> al3 = new TreeSet<Student>(new ComparaName());
		al3.add(new Student("abc",12));
		al3.add(new Student("dgh",11));
		//把学生和工人都加入al1集合
		al1.addAll(al3);
		al1.addAll(al2);
		//都按照Man的排序规则排序
		Iterator<Man> it = al1.iterator();
		while(it.hasNext())
			System.out.println(it.next());
	}
}

五、通配符的体现

import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;

public class Main 
{
	public static void main(String[] args) {
		
		ArrayList<Man> al1 = new ArrayList<Man>();
		al1.add(new Man("ABC",12));
		al1.add(new Man("DGH",11));
		
		ArrayList<Man> al2 = new ArrayList<Man>();
		al2.add(new Man("ABC",12));
		al2.add(new Man("DGH",11));
		
		boolean flag1 = al1.containsAll(al2);
		System.out.println(flag1);
		
		ArrayList<String> al3 = new ArrayList<String>();
		al3.add("qwertyi");
		al3.add("asd");
		
		boolean flag2 = al1.containsAll(al3);
		System.out.println(flag2);
	}
	//方法 : containsAll(Collection <?> c) 
	//?不论传什么都接收,就好比Object里的equals方法:"asd".equals(new Worker("asd",12)),编译和运行都是通过的
	public static void show(Collection<?> al){
		for(Iterator<?> it = al.iterator();it.hasNext();){
			System.out.println(it.next());
		}
	}
}



JAVA学习第四十二课 — 泛型(二)—泛型接口&&通配符应用