Java集合框架(三)---泛型

  1. 泛型类
  2. 泛型方法
  3. 静态方法泛型
  4. 泛型接口
  5. 泛型限定

泛型:JDK1.5版本以后出现新特性,用于解决安全问题,是一个类型安全机制

好处:
1.将运行时期出现问题ClassCastException,转移到了编译时期。方便于程序员解决问题,让运行事情问题减少,安全。
2.避免强制转换麻烦

泛型格式:
通过<>来定义要操作的引用数据类型。

在使用Java提供的对象中,什么时候写泛型呢?通常在集合框架中很常见,只要见到<>就要定义泛型。当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

Demo1:

public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
	//只能存储String类型的字符
	ArrayList<String> aList = new ArrayList<String>();
	aList.add("aaa");
	//用迭代器取出的元素,也需要明确迭代类型
		Iterator<String> iterator = aList.iterator();
		while (iterator.hasNext()) {
			sop(iterator.next());
		}
	}

Demo2:

public class Demo {
	public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
	
		TreeSet<String> treeSet = new TreeSet<String>(new MyCompare());
		 treeSet.add("ddfv");
		 treeSet.add("saaa");
		 treeSet.add("fv");
		 
		Iterator<String> iterator = treeSet.iterator();
		while (iterator.hasNext()) {
			String string = iterator.next();
			sop(string); 
		}
	}
}
class MyCompare implements Comparator<String>{
	@Override
	public int compare(String o1, String o2) {
		int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
		if (num == 0)  {
			return o1.compareTo(o2);
		}
		return num;
	}
}

泛型类

什么时候定义泛型类?当类中要操作的引用类型不确定的时候,早期定义Object来完成,使用Object要进行强转,而现在定义泛型来完成扩展。

public class Demo {
	public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
	
		Utils<Work> utils = new Utils<Work>();
		utils.setQq(new Work());
		//使用泛型类,不需要进行强转
		Work uWork = utils.getQq();
		
		/*Tool tool = new Tool();
		tool.setObject(new Work());
		//需要进行强转
		Work work = (Work)tool.getObject();*/
	}
}
class Work{	}
class Student{}
//泛型类
class Utils<QQ>{
	private QQ qq;
	public void setQq(QQ qq) {
		this.qq = qq;
	}
	public QQ getQq() {
		return qq;
	}
}
//泛型前做法
class Tool{
	private Object object;
	public void setObject(Object object) {
		this.object = object;
	}
	public Object getObject() {
		return object;
	}
}

泛型方法

泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了,为了让不同方法可以操作不同的对象,而且类型还不确定,那么可以将泛型定义在方法上。

public static void main(String[] args) {
		
	DemoMothd demoMothd = new DemoMothd();
	
	demoMothd.show("hahha");
	demoMothd.show(5);
	demoMothd.print("aaa");
	}
}
class DemoMothd{
//泛型方法
	public <T> void show(T t){
		System.out.println("show:"+t);
	}
	public <Q> void print(Q q){
		System.out.println("print:"+q);
	}
}

同样泛型方法和泛型类也是可以共同存在的

public static void main(String[] args) {
		
	DemoMothd<String> demoMothd = new DemoMothd<String>();
	
	demoMothd.show("hahha");
	//demoMothd.show(5);这样是不能传int类型,因为DemoMothd的泛型是String,它所属的show方法类型是跟随DemoMothd对象的泛型,而print方法有自己的泛型类型,所以不跟随DemoMothd对象的类型。
	
	demoMothd.print(5);
	demoMothd.print("aaa");
	}
}
class DemoMothd<T>{
	public  void show(T t){
		System.out.println("show:"+t);
	}
	public <Q> void print(Q q){
		System.out.println("print:"+q);
	}
}

打印:

show:hahha
print:5
print:aaa

静态方法泛型

静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

	public static void main(String[] args) {
		
	DemoMothd<String> demoMothd = new DemoMothd<String>();
	
	demoMothd.show("hahha");
	
	demoMothd.print(5);
	demoMothd.print("aaa");
	
	DemoMothd.method("静态方法泛型");
	}
}
class  DemoMothd<T>{
	public  void show(T t){
		System.out.println("show:"+t);
	}
	public <Q> void print(Q q){
		System.out.println("print:"+q);
	}
	//静态先加载后有对象,所以静态方法不可以访问类上定义的泛型
	public static <W> void method(W w){
		System.out.println("method:"+w);
	}
}

打印结果:

show:hahha
print:5
print:aaa
method:静态方法泛型

泛型接口

不是很常见

public static void main(String[] args) {
		
		InterImpl impl = new InterImpl();
		impl.show("InterImpl");
	
		InterImpl2<Integer> impl2 = new InterImpl2<Integer>();
		impl2.show(666);
	}
}
//泛型定义在接口上
interface Inter<T>{
	void show(T t);
}
class InterImpl implements Inter<String>{
	@Override
	public void show(String t) {
		System.out.println("InterImpl = "+t);
		}
	}
class InterImpl2<T> implements Inter<T>{
	@Override
	public void show(T t) {
		System.out.println("InterImpl2 =" +t);
	}
	
}

打印:

InterImpl = InterImpl
InterImpl2 =666

泛型限定

?通配符,也可以理解为占位符
? extends E:可以接收E类型或者E的子类型,上限
? super E :可以接收E类型或者E类型的父类型,下限

Demo 1
?通配符,也可以理解为占位符

public class Demo {
	public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
		 
		ArrayList<String> arrayList = new ArrayList<String>();
		arrayList.add("asddd");
		arrayList.add("asddd");
		
		ArrayList<Integer> arrayList2 = new ArrayList<Integer>();
		arrayList2.add(3);
		arrayList2.add(2);
	//proColl方法可以接收ArrayList任意类型对象
		proColl(arrayList);
		proColl(arrayList2);
	}
	//?为通配符,不明确对象类型
	public static void proColl(ArrayList<?> aList) {
		Iterator<?> iterator = aList.iterator();
		while (iterator.hasNext()) {
			Object obj = iterator.next();
			sop(obj); 
	 }
	}
		/*也可以定义为静态泛型T,T可以明确对象
		public static <T> void proColl2(ArrayList<T> aList) {
			Iterator<T> iterator = aList.iterator();
			while (iterator.hasNext()) {
				T t = iterator.next();
				sop(t); 
		}
	}*/
}

Demo 2
? extends E:可以接收E类型或者E的子类型,上限

public static void main(String[] args) {
		 
		ArrayList<Person1> arrayList = new ArrayList<Person1>();
		arrayList.add(new Person1("aaa"));
		arrayList.add(new Person1("ddd"));
		
		ArrayList<Student> arrayList2 = new ArrayList<Student>();
		arrayList2.add(new Student("stu1"));
		arrayList2.add(new Student("stu2"));
		
		proColl2(arrayList);
		proColl2(arrayList2);
	}
	//只打印student子类和Person父类
	public static void proColl2(ArrayList<? extends Person1> aList) {
		Iterator<? extends Person1> iterator = aList.iterator();
		while (iterator.hasNext()) {
			Person1 t = iterator.next();
			sop(t.getName()); 
	}
}
class Person1{
	private String name;
	public Person1(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
}
class Student extends Person1{
	public Student(String name) {
		super(name);
	}
}

打印:

aaa
ddd
stu1
stu2

Demo 3
? super E :可以接收E类型或者E类型的父类型,下限

//一个Person1父类
class Person1{
	private String name;
	public Person1(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
}
//Student 子类
class Student extends Person1{
	public Student(String name) {
		super(name);
	}
}
//Worker 子类
class Worker extends Person1{
	public Worker(String name) {
		super(name);
	}
}
public static void main(String[] args) {
//传入Student比较器
		TreeSet<Student> tSet= new TreeSet<Student>(new MyCompare());
		tSet.add(new Student("addd1"));
		tSet.add(new Student("addd2"));
		tSet.add(new Student("addd3"));
		 
		Iterator<Student> iterator = tSet.iterator();
		while (iterator.hasNext()) {
			Student t = iterator.next();
			sop(t.getName()); 
		}
		//Worker传入比较器
		TreeSet<Worker> tSetWork= new TreeSet<Worker>(new MyCompare());
		tSetWork.add(new Worker("Work1"));
		tSetWork.add(new Worker("Work2"));
		tSetWork.add(new Worker("Work3"));
		 
		Iterator<Worker> iteratorWork = tSetWork.iterator();
		while (iteratorWork.hasNext()) {
			Worker t = iteratorWork.next();
			sop(t.getName()); 
		}
	}
//为什么这里传入的是父类类型,因为TreeSet接收的是<? super E>,如果传入Student 那么这个比较器只能被TreeSet<Student>类型用,如何传入Worker类,只能被TreeSet<Worker>用,而Person1是既可以被TreeSet<Student>用也可以被TreeSet<Worker>用,这样就很方便了。
class MyCompare implements Comparator<Person1>{
	@Override
	public int compare(Person1 o1, Person1 o2) {
		return o1.getName().compareTo(o2.getName());
	}
}

源码展示:

    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

打印结果:

addd1
addd2
addd3
Work1
Work2
Work3
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值