Java之泛型

泛型的概念

1.为什么要使用泛型?
不使用泛型的案例:

List list1 = new ArrayList();
list.add("张三");
list.add(20);
list.add(100.00);
......
//获取元素
//获取第一个元素
String name = (String)list.get(0);
//获取第二个元素
int age = (Integer)list.get(1);
//获取第三个元素
double score = (Double)list.get(2);
......

代码分析:
集合与数组不同.数组只能存储单一的数据类型,而集合中可以存储任意的数据类型,可以是字符串,可以是整型,也可以是浮点型,这造成了两个问题
1.每使用一个元素就要进行向下转型,导致代码冗余
2.容易发生类型转换异常,安全性不高
所以泛型时为了解决这些问题的

2.泛型的概念:

ArrayList<String> arrList1 = new ArrayList<String>();
ArrayList<Integer> arrList2 = new ArrayList<Integer>();
//getClass();方法:获取字节码文件名
Class c1 = arrList1.getClass();
Class c2 = arrList2.getClass();
//判断c1,c2的字节码文件是否相同
System.out.println(c1 == c2);//结果为true

代码分析:无论是对于ArrayList<String>还是 ArrayList<Integer>,他们的Class类型是一致的,都是ArrayList.class。

那么他们明明有指定类型的差异,这个差异到底体现在哪里呢?

答案是体现在类编译的时候,当JVM进行类编译的时候会进行泛型检查,如果说一个List被声明为String类型,那么他往该集合存取数据的时候就会对数据进行判断,从而就避免了存入或取出错误的数据。

这也就是说,泛型只存在于编译阶段,而不存在于运行阶段

泛型的知识点

1.迭代器的使用和增强for循环
迭代器(Iterator):
作用:对集合进行遍历
常用方法:
1.boolean hasNext( ):如果仍有元素可以迭代,则返回true
2.E next( );返回迭代的下一个元素,去除集合中的下一个元素
hasNext()和next()方法的原理:
在这里插入图片描述
迭代器的使用步骤:
1.先使用集合中Collection的方法iterator( )获取迭代器实现类对象,使用Iterator接口接收(多态)
2.使用Iterator接口中的方法hasNext( )判断还有没有下一个元素
3.使用Iterator的next方法取出下一个元素

Iterator是一个接口,无法直接访问,需要用Iterator的实现类进行访问,
获取实现类的方式比较特殊:Collection接口中有一个方法叫做"iteractor()"
这个方法的返回值就是迭代器的实现对象
Iterator iterator( ) //返回在此Collection的集合元素上进行迭代的迭代器

代码实现:

public class IteratorDemo {
	public static void main(String[] args) {
		Collection<String> coll = new ArrayList<>();//多态
		//向集合里添加元素
		coll.add("张三");
		coll.add("李四");
		coll.add("王五");
		coll.add("赵六");
	//1.先使用集合中Collection的方法iterator( )获取迭代器实现类对象,使用Iterator接口接收(多态)
	//注意:
		//Iterator是有泛型的,泛型的实际类型是根据Collection集合的泛型进行定义
		
		//Iterator接口<泛型> 对象名 = 实现类对象 -----多态
		Iterator<String> it = coll.iterator();//多态
		
		// 2.使用Iterator接口中的方法hasNext( )判断还有没有下一个元素
		boolean isNext = it.hasNext();
		System.out.println(isNext);
		
		// 3.使用Iterator的next方法取出下一个元素
//		String s = it.next();
//		System.out.println(s);
//		s = it.next();
//		System.out.println(s);
//		s = it.next();
//		System.out.println(s);
//		s = it.next();
//		System.out.println(s);
//		
		//循环取出集合中的元素
		while(it.hasNext( )) {
			String s1 = it.next();
			System.out.println(s1);
		}
		

增强for循环:
增强for循环的本质是迭代器,只适用于取出数组和集合的元素
代码实现:

//增强for循环的使用:
		//增强for循环的底层实现是迭代器,使用for循环格式简化了迭代器的复杂性
		//只能在集合或者数组中使用
		//格式
		//for(集合/数组的数据类型 变量名 : 集合名/数组名){
								//输出元素;
	//					}
		
		//遍历数组:
		int[] arr = {1,2,3,4,5,6,7,8,9,10};
		for (int i : arr) {
			System.out.println(i);
		}
		//遍历集合
		for(String s : coll) {
			System.out.println(s);
		}

2.泛型类
代码实现:

public class GenericClass <T> {
	//T 代表类型参数
	//泛型:是指类型参数化,处理的数据类型不是固定的,而是可以作为参数传入
	T first;
	T second;
	public GenericClass(T first,T second) {
		this.first = first;
		this.second = second;
	}
	/**
	 * @return first
	 */
	public T getFirst() {
		return first;
	}
	/**
	 * @return second
	 */
	public T getSecond() {
		return second;
	}
	
}
//多个类型参数泛型类
class GenericClass2 <U,V>{
	U first;
	V second;
	public GenericClass2(U first, V second {
		this.first = first;
		this.second = second;
	}
	/**
	 * @return first
	 */
	public U getFirst() {
		return first;
	}
	/**
	 * @return second
	 */
	public V getSecond() {
		return second;
	}
}

//以普通类作为泛型类
class GenericClass3{
	Object first;
	Object second;
	public GenericClass3(Object first, Object second) {
		this.first = first;
		this.second = second;
	}
	/**
	 * @return first
	 */
	public Object getFirst() {
		return first;
	}
	/**
	 * @return second
	 */
	public Object getSecond() {
		return second;
	}
	
}

测试:

public class GenericClassDemo {
	public static void main(String[] args) {
		//使用泛型类
		
		//Integer 是实际的类型参数
		GenericClass<Integer> minmax = new GenericClass<Integer>(1,100);
		Integer min = minmax.getFirst();
		Integer max = minmax.getSecond();
		System.out.println(min);
		System.out.println(max);
		
		//实际类型参数是可以改变的
		
		//String 是实际类型参数
		GenericClass<String> name = new  GenericClass<String>("张三","李四");
		String name1 = name.getFirst();
		String name2 = name.getSecond();
		System.out.println(name1);
		System.out.println(name2);
		
		//多个类型参数泛型类
		GenericClass2<String,Integer> name_age = new GenericClass2<String,Integer>("张三",20);
		String name3 = name_age.getFirst();
		int age = name_age.getSecond();
		System.out.println(name3);
		System.out.println(age);
		
		//以Object类作为泛型类
		GenericClass3 objMinMax = new GenericClass3(1,100);
		Integer min1 = (Integer)objMinMax.getFirst();
		Integer max1 = (Integer)objMinMax.getSecond();
		System.out.println(min1 + "  " + max);
	}
}

3.泛型方法
代码:

public class Generic {
	public static void main(String[] args) {
		// 创建泛型类对象
		GenericClass<String,Integer,String> coll = new GenericClass<String,Integer,String>("张三",19,"男");
		System.out.println(coll.getName());
		System.out.println(coll.getAge());
		System.out.println(coll.getSex());
		
		// 调用含有泛型的方法
		GenericMethod.method("李四");
		GenericMethod.method(19);
		GenericMethod.method(true);
		GenericMethod.method(100.0);
		
		GenericMethod.method2("hello", "world");
}
class GenericMethod{
	// 定义含有泛型的方法
	//在调用含有泛型的方法时,确定方法的数据类型,传递给这个方法的参数是什么类型的,这个泛型就是什么类型的
	public static <T> void method(T t) {
		System.out.println(t);
	}
	// 含有多个泛型的方法
	public static <T,V> void method2(T t , V v) {
		System.out.printf("%s%s",t,v);
	}
}

4.泛型接口

//泛型接口
public interface GenericInterface<T> {
	public abstract void method(T t);
}
//接口的实现类
//实现接口,并且指定接口的泛型
class GenericInterfaceImplementsClass implements GenericInterface<String>{

	@Override
	public void method(String t) {
		// TODO 自动生成的方法存根
		System.out.println(t);
	}
}

//创建含有泛型的接口实现类
class GenericInterfaceImplementsClass2<T> implements GenericInterface<T>{

	@Override
	public void method(T t) {
		// TODO 自动生成的方法存根
	System.out.println(t);	
	}
	
}

测试:


public class GenericInterfaceDemo {
	public static void main(String[] args) {
		GenericInterfaceImplementsClass test = new GenericInterfaceImplementsClass();
		test.method("泛型接口");
		System.out.println("==============================");
		GenericInterfaceImplementsClass2<String> test2 = new GenericInterfaceImplementsClass2<>();
		test.method("含有泛型的接口实现类");
	}
}

总结:
泛型就是在定义的时候不知道是什么类型,创建含有泛型的对象或者调用含有泛型的方法时再指定数据类型,然后把数据类型传给用字母代替的泛型,最后编译器会根据传递过去的数据类型执行相应的代码.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值