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

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

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

好处:

1.将运行时期出现问题ClassCastException,转移到了编译时期。方便于程序员解决问题,让运行事情问题减少,安全。

2.避免强制转换麻烦

泛型格式:

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

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

Demo1:

java 复制代码
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:

java 复制代码
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要进行强转,而现在定义泛型来完成扩展。

java 复制代码
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;
	}
}

泛型方法

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

java 复制代码
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);
	}
}

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

java 复制代码
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);
	}
}

打印:

bash 复制代码
show:hahha
print:5
print:aaa

静态方法泛型

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

java 复制代码
	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);
	}
}

打印结果:

bash 复制代码
show:hahha
print:5
print:aaa
method:静态方法泛型

泛型接口

不是很常见

java 复制代码
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);
	}
	
}

打印:

bash 复制代码
InterImpl = InterImpl
InterImpl2 =666

泛型限定

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

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

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

Demo 1

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

java 复制代码
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的子类型,上限

java 复制代码
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);
	}
}

打印:

bash 复制代码
aaa
ddd
stu1
stu2

Demo 3

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

java 复制代码
//一个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());
	}
}

源码展示:

java 复制代码
    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

打印结果:

bash 复制代码
addd1
addd2
addd3
Work1
Work2
Work3
相关推荐
Theodore_10223 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
冰帝海岸4 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象4 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了5 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
----云烟----5 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024065 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
小二·5 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic5 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it5 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
懒洋洋大魔王5 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq