Java-泛型

泛型:是一种未知的数据类型,当我们不知到使用什么数据类型的时候可以使用泛型

泛型也可以看成是一个变量,用来接收数据类型:
E e :Element 元素 | T E Type 类型
ArrayList集合在定义的时候,不知道集合中都会有什么数据类型,所以类型使用泛型
public class ArrayList{
public boolean add(E e){}
public E get(int index){}

}
	创建集合对象的时候就会确定泛型的数据类型
	会把数据类型作为参数传递,赋值给泛型.

使用泛型的好处:
=================
	public class FanXingCls {

	public static void main(String[] args) {
//		show01();
		show02();
	}
	/*
	 * 创建集合对象,不使用泛型
	 * 好处:	集合不使用泛型,默认的了行就是Object类型,可以存储任意类型的数据
	 * 弊端: 不安全,会引发异常
	 * 
	 */
	private static void show01(){
		//不使用泛型创建集合。
		ArrayList list = new ArrayList();
		list.add("abc");
		list.add(1);
		//使用迭代器遍历集合
		//获取迭代器
		Iterator it = list.iterator();
		it.hasNext();
		while(it.hasNext()){
			//取出元素也是Object类型
			Object obj = it.next();
			System.out.println(obj);
			//想要使用String类特有的方法length获取字符串的长度,不能使用
			//多态 Object obj = "abc";
			//需要向下转型
			//会抛出java.lang.ClassCastException,不能把Integer转换为String,所以不使用泛型不安全
			String s = (String) obj;
			System.out.println(s.length());			
		}		
	}
	/*
	 * 创建集合对象,使用泛型
	 * 好处:避免了类型转换异常,,存储什么类型,就取出什么类型
	 * 	       把运行期异常(代码运行之后会抛出的异常),提升到编译器
	 * 弊端:存储的类型必须一致
	 */
	private static void show02(){
		ArrayList<String> list = new ArrayList<>();
		list.add("abc");
		list.add("bcd");
		//使用迭代器遍历集合
		//也可用上面的是方法遍历.
		for (String string : list) {
			System.out.println(string);
			System.out.println(string.length());
		}
	}
}

泛型类

定义一个含有泛型的类,模拟ArrayList集合
泛型是一个未知的数据类型,当我们不确定是用什么类型的时候,可以使用泛型
泛型可以使用任意的数据类型,可以使用Integer,String,Student.

这样就定义了一个含有泛型的类

====================

//含有泛型的类。
public class GenerClass<E> {

	private E name;

	public E getName() {
		return name;
	}

	public void setName(E name) {
		this.name = name;
	}
}

-------------------------------
//使用含有泛型的类,定义类,使用的时候传递什么类型的类就是什么类型的类。
public class GenerClaTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//不写泛型默认为Object类型
		GenerClass gc = new GenerClass();
		gc.setName("字符串");
		Object name = gc.getName();
		
		//创建GennericClass对象,泛型使用Integer类型
		//使用时添加泛型
		GenerClass<Integer>  gc2 = new GenerClass<>();
		gc2.setName(1);
		Integer name2 = gc2.getName();
		//使用字符串
		GenerClass<String>  gc3 = new GenerClass<>();
		gc3.setName("张天爱");
		String name3 = gc3.getName();
	}
}

=======================

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

/*
 * 		了解怎么使用这些东西。
 * 	泛型的上限限定和下限限定:
 * 		上限限定:  ? extend E  代表使用的泛型只能是E类型的子类或本身
 * 		下限限定:  ? super E	代表使用的泛型只能是E类型的父类或本身
 * 
 */
public class FanXingGeneric {

	public static void main(String[] args) {
		Collection<Integer> list1 = new ArrayList<Integer>();
		Collection<String> list2 = new ArrayList<String>();
		Collection<Number> list3 = new ArrayList<Number>();
		Collection<Object> list4 = new ArrayList<Object>();
		
		getElement(list1);
//		getElement(list2);//报错String类型与Number类型无关系
		getElement(list3);
//		getElement(list4);//报错Object类型是Number的父类
		
		//下面的逻辑原理类同.
		/*
		 * 类与类之间的继承关系
		 * Integer extends Number extends Object
		 * String extends Object
		 * 
		 */
	}

	//泛型的上限,此时的泛型? 必须是number类型或者是number类型的子类
	private static void getElement(Collection<? extends Number> list1) {
		// TODO Auto-generated method stub
		
	}
	//泛型的上限,此时的泛型? 必须是number类型或者是number类型的父类
	private static void getElement2(Collection<? super Integer> list1) {
		// TODO Auto-generated method stub
		
	}
}

-------------------------------------------
import java.util.ArrayList;
import java.util.Iterator;

/*
 * 	泛型的通配符:
 * 		?代表任意的数据类型
 * 
 *	不能创建对象使用
 *	只能作为方法的参数使用
 * 
 */
public class GenericCls {

	public static void main(String[] args) {
		//固定类型的泛型。
		ArrayList<Integer> list01 = new ArrayList<>();
		list01.add(1);
		list01.add(2);
		
		ArrayList<String>  list02 = new ArrayList<>();
		list02.add("a");
		list02.add("b");
		
		printArray(list01);
		printArray(list02);
		//public static void printArray(ArrayList<Integer> list){
		//当这个泛型确定的时候,这两个参数的方法可定有一个报错,所以我们可以使用泛型通通配符来解决
	}
	/*
	 * 定义一个方法,能遍历所有类型的ArrayList集合
	 * 这时候我们不知道ArrayList集合使用什么类型数据,可以使用泛型通配符来接收数据类型.
	 * 		泛型没有继承概念的
	 * 	
	 */
	//定义一个方法,代表泛型,这个泛型可以传递任何的数据类型,用通配符来完成。
	public static void printArray(ArrayList<?> list){
		//使用迭代器遍历集合,遍历集合
		Iterator<?> it = list.iterator();
		while(it.hasNext()){
			//it.next()方法,取出的元素是Object,可以接收任意的数据类型
			Object o = it.next();
			System.out.println(o);	
		}
		for (Object object : list) {
			System.out.println("增强for"+object);
		}
	}
}

定义含有泛型的方法:

	泛型定义在方法的修饰符和返回值之间
 格式:
	修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)){
			方法体;
	}

含有泛型的方法,在调用方法的时候确定泛型的数据类型
传递什么类型的参数,反省就是什么类型.

===================

public class GennerMethod {

	//定义一个含有泛型的方法
	public <M> void method01(M m){
		System.out.println(m);
	}
	
	//定义一个含有泛型的静态方法
	public static <S> void method02(S s){
		System.out.println(s);
	}
	
}

------------------------------
public class GennerMethodTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		GennerMethod gm = new GennerMethod();
		/*
		 * 传递什么类型的数据
		 * 泛型就是什么类型
		 * 
		 */
		gm.method01(10);
		gm.method01("abc");
		gm.method01(true);
		
		gm.method02("静态方法,不建议创建对象使用,通过类名.方法名使用");
		GennerMethod.method02("静态方法");
		GennerMethod.method02(1);
		
	}

} 

===========================

泛型接口:

==========================

public interface GennerInterface<I> {

	public abstract void method(I i);
}

-----------------------------------
/*
 * 含有泛型的接口第一种使用方式:
 *  第一种使用方式;定义接口的实现类,实现接口,指定接口的泛型
 *  public interface Iterator<E>{
 *  		E next();
 *  }
 *  Scanner类实现了Iterator接口,并指定接口泛型为字符串,所以重写的next方法泛型默认就是String
 *  public final class Scanner implements Iterator<String>{
 *  		public String next(){}
 *  }
 *  
 */
//一想到接口,就必须想到的是实现类。
public class GennerInterfaceImpl implements GennerInterface<String>{

	//传递指定好的类型。
	@Override
	public void method(String i) {
		// TODO Auto-generated method stub
		
	}

}


-----------------------------------
/*
 * 第二种使用方式:
 *   接口是用什么泛型,实现类就是用什么泛型,类跟着接口走
 *   就相当于含有泛型的类,创建对象的时候确定泛型的类型
 *   public interface List<E>{
 *   		boolean add(E e);
 *   		E get (int index);
 *   }
 * 	 public class ArrayList<E> implements List<E>{
 * 			public boolean add(E e);
 * 			public E get(int index);
 * 	 }
 * 
 * 
 * 
 */
public class GennerInterfaceImpl02<I> implements GennerInterface<I>{

	@Override
	public void method(I i) {
		// TODO Auto-generated method stub
		System.out.println(i);
	}
}

------------------------------------
/*
 * 测试含有泛型的接口
 * 
 * 
 */
public class GennerInterfaceTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建,先前指定好类型
		GennerInterfaceImpl gif = new GennerInterfaceImpl();
		gif.method("字符串");
		
		//创建,现在指定类型
		GennerInterfaceImpl02<Integer> gif2 = new GennerInterfaceImpl02<>();
		gif2.method(10);
		
		//创建,随后现在指定类型。
		GennerInterfaceImpl02<Double> gif3 = new GennerInterfaceImpl02<>();
		gif3.method(3.141592653);
	}

}

=============================

迭代器

java.util.Iterator接口:迭代器(对集合进行遍历)
Iterator接口介绍:
迭代器:一种通用取出元素的方式
在取出元素之前先判断集合中有没有元素,如果有就把这个元素取出来,继续在判断,
一直把集合中所有元素全部取出来。
通用方法:
boolean hasNext();
如果仍有元素可以迭代,则返回true
E next() 返回迭代的下一个元素 取出集合中下一个元素
Iterator接口,我们无法直接使用,所以需要使用接口的实现类对象
Collection接口有一个方法,叫iterator() 这个方法返回的就是迭代器的是实现类对象
Iterators iterator() 返回在此 collection 的元素上进行迭代的迭代器

迭代器的使用步骤:

	使用集合中的方法iterator 获取迭代器的实现类对象,使用Iterator接口接收(多态)
	使用Iterator接口中的方法hashNext()判断有没有下一个元素
	使用Iterator接口中的方法next取出集合中的下一个元素. 

Iterator接口也是有泛型的,迭代器的泛型也跟着集合走,集合是什么反省,迭代器就是什么泛型。

=======================

public class IteratorCls {

	public static void main(String[] args) {
		Collection<String> coll = new ArrayList<>();
		//往集合中添加元素
		coll.add("马化腾");
		coll.add("马云");
		coll.add("刘强东");
		
		System.out.println("-------------------------------");
		
		//获取迭代器     coll.iterator(); 多态
		Iterator<String> it = coll.iterator();
		//创建一个集合
		/*
		 * 我们发现代码是一个重复的过程
		 * 不知道集合中有多少个元素,所以使用while循环.
		 * 循环结束的条件hasNext方法返回true
		 * 
		 */
		while(it.hasNext()){
			String e = it.next();
			System.out.println(e);
		}
		//下面没有元素所以会报错.
		System.out.println("------------------------------------");

		for(Iterator<String> it2 = coll.iterator();it2.hasNext();){
			String e = it2.next();
			System.out.println(e);
		}
		
		//使用Iterator接口中的方法hashNext()判断有没有下一个元素
		boolean b = it.hasNext();
		//把元素取出来
		String next = it.next();
		System.out.println(next);
		//这一步是还有接着取。
		b = it.hasNext();
		//把元素取出来
		next = it.next();
		System.out.println(next);
		
		b = it.hasNext();
		//把元素取出来
		next = it.next();
		System.out.println(next);
		//我们发现这样取有点麻烦
		//而且没有元素.在取出元素抛出NoSuchElementException 没有元素异常.
		
	}
	
}

=========================

增强for

增强for循环:的曾使用的是迭代器,使用for循环的格式,简化了迭代的写法
是JDK1.5之后出现的新特性
所有单例集合都可以使用增强for
Collection extends Iterable
public interface Iterable:实现这个接口允许对象成为"foreach"语句的目标对象

	格式(集合/数组的数据类型     变量名   : 集合名/数据名){
		syso(变量名)
	}
	遍历的目标只能是集合和数组.
	=================
public class ZengQiangFor {

	public static void main(String[] args) {
		demo01();
		demo02();
	}
	//遍历数组
	private  static void demo01(){
		int[] arr = {1,2,3,4,5};
		for(int i : arr){
			System.out.println(i);
		}
		
	}
	//遍历集合。
	private static void demo02(){
		ArrayList<String> list = new ArrayList<>();
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		list.add("ddd");
		for (String s : list) {
			System.out.println(s);
		}
		
	}
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值