Java学者日记 泛型与集合

泛型,集合(含泛型)

一、泛型简介

       泛型是一种我们常用的程序设计手段,使用泛型机制编写的程序代码要比那些杂乱的使用Object变量。然后进行强制类型转换的代码具有更好的安全性和可读性。泛型对于集合类尤其有用,例如,ArrayList就是一个无处不在的集合类

二、为什么要使用泛型程序设计

       泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用。例如,一个ArrayList类可以聚集任何类型的对象,这就是一个泛型程序设计的实例。

三、泛型的使用

     1.集合中的使用

      ①在集合中不使用泛型的情况下,举一个例程:

	@Test
	public void test1() {
		List list = new ArrayList();
		list.add(85);
		list.add(88);
		list.add(70);
		// 1.未使用泛型,可以加任何Object类型对象
		list.add(new String("AA"));

		for (int i = 0; i < list.size(); i++) {
			// 强转错误,报ClassCastException
			int score = (Integer) list.get(i);
			System.out.println(score);// 此时new String转化错误
		}

	}

       在IDE中,未使用泛型的集合会报warning,告诉开发者应使用泛型。并且当进行强制转换时,会产生一个异常。

       ②在集合中使用泛型的情况下,举一个例程:

	// 2.在集合中使用泛型
	@Test
	public void test2(){
		List<Integer> list = new ArrayList<>();
		list.add(78);
		list.add(87);
//		list.add(new String("AA")); 错误!只能添加Integer类型的数据
//		for (int i = 0; i < list.size(); i++) { //另一种遍历方式
//			int score = list.get(i);
//			System.out.println(score);
//		}
		
		Iterator<Integer> it = list.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
	}

         运行后,不报warning,无异常发生。

        2.自定义泛型类

        一个泛型类就是具有一个或多个类型变量的类,以自定义Order类为例:

class Order<T> {
	private String orderName;
	private int orderId;
	private T t;
	List<T> list = new ArrayList<>();

	public T getT() {
		return t;
	}

	public void add() {
		list.add(t);
	}



	@Override
	public String toString() {
		return "Order [orderName=" + orderName + ", orderId=" + orderId + ", t=" + t + "]";
	}

	public void setT(T t) {
		this.t = t;
	}

	public String getOrderName() {
		return orderName;
	}

	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}

	public int getOrderId() {
		return orderId;
	}

	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}
}

        Order类引入了一个类型变量T,泛型类也可以有多个类型变量,例如:

        class Order<T,U>{...}

        类定义中的类型变量指定方法的返回类型以及域和局部变量的类型。例如:

        

private T t;

        3.泛型方法

        实际上,还可以定义一个带有类型参数的简单方法:

	public <E> E getE(E e) {
		return e;
	}

        注意,类型变量放在修饰符(此处为public)的后面,返回类型(此处为E)的前面。这样的方法称为泛型方法。

        下面根据一个例程来了解自定义泛型类和泛型方法的使用

package generic;

import java.util.ArrayList;
import java.util.List;

//泛型类使用二:自定义泛型类
public class TestOrder {
	// 自定义泛型类使用
	public static void main(String[] args) {
		Order<Boolean> order = new Order<>();
		order.setT(true);
		System.out.println(order.getT());
		order.add();
		List<Boolean> list = order.list;
		System.out.println(list);

		SubOrder o = new SubOrder();
		List<Integer> list1 = o.list;
		System.out.println(list1);
		// 调用泛型方法
		Integer i = order.getE(35);
		Double d = order.getE(56.5);

		Integer[] in = new Integer[] { 1, 2, 3 };
		List<Integer> list2 = new ArrayList<>();
		List<Integer> list3 = order.FromArrayToList(in, list2);
		System.out.println(list3);
	}

}

class Order<T> {
	private String orderName;
	private int orderId;
	private T t;
	List<T> list = new ArrayList<>();

	public T getT() {
		return t;
	}

	public void add() {
		list.add(t);
	}

	// 泛型类使用三:声明泛型方法
	public <E> E getE(E e) {
		return e;
	}

	// 泛型方法:
	public <E> List<E> FromArrayToList(E[] e, List<E> list) {
		for (E e1 : e) {
			list.add(e1);
		}
		return list;

	}

	@Override
	public String toString() {
		return "Order [orderName=" + orderName + ", orderId=" + orderId + ", t=" + t + "]";
	}

	public void setT(T t) {
		this.t = t;
	}

	public String getOrderName() {
		return orderName;
	}

	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}

	public int getOrderId() {
		return orderId;
	}

	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}
}

// 继承泛型类或者泛型接口时,可以指明泛型类型
class SubOrder extends Order<Integer> {
	// 不指明:class SubOrder<T> extends Order<T>

}

  四、泛型的继承规则

        举个例子来说明继承规则

	/*
	 * 泛型与继承的关系:
	 * 若类A是类B的子类,那么List<A>不是List<B>的子接口(类)
	 */
	@Test
	public void test4(){
		Object obj = null;
		String str = "AA";
		obj = str;
		
		Object[] obj1 = null;
		String[] str1 = new String[]{"AA","BB","CC"};
		obj1 = str1;  //非泛型
		
		List<Object> list = null;
		List<String> str2 = new ArrayList<>();
//		list = str2; 错误!
		
	}

        若类A是类B的子类,那么List<A>不是List<B>的子接口(类),这就是泛型类的继承规则。即无论A,B有什么关系,通常List<A>与List<B>并没有什么联系。

五、通配符类型

  当普通的类的继承不适用于泛型类时,为了实现继承关系,可使用通配符来完成

	/*
	 * 通配符:?
	 * List<A>,List<B>...都是List<?>的子类
	 * 
	 * ? extends A: 可以存放A及其子类
	 * ? super A:可以存放A及其父类
	 */
	@Test
	public void test5(){
		List<?> list = null;
		List<Object> list1 = new ArrayList<>();
		List<String> list2 = new ArrayList<>();
		list = list1;
		list = list2;
	}



猜你喜欢

转载自blog.csdn.net/qq_42368456/article/details/81048123