泛型-泛型类、接口、方法

时间:2021-03-15 19:23:21

为什么要使用泛型?优点在哪里?

使用java泛型的动机在编译时检测出错误。

一、泛型方法

可以为静态方法定义为泛型类型!

1、非受限泛型:<T> 等价于受限泛型<T extends Object>

public class GenericMethodDemo {
    public static void main(String[] args) {
    	Integer[] integers = {1,2,3,4,5,6};
    	String[] strings = {"London","Paris","New York","Austin"};
/*    	GenericMethodDemo.<Integer>print(integers);
    	GenericMethodDemo.<String>print(strings);*/
    	//也可以换成以下形式
    	print(integers);
    	print(strings);
    }
    
    public static <E> void print(E[] list) {
    	for (int i = 0; i < list.length; i++) {
			System.out.print(list[i] + " ");
		}
    	System.out.println();
    }
}

public class Bounded {

	public static void main(String[] args) {
        Integer a = new Integer(1);
        Integer b = new Integer(2);
        System.out.println(equals(a, b));
        String s1 = new String("123");
        String s2 = new String("123");
        System.out.println(equals(s1, s2));
	}
	
    //等价于<E>非受限泛型
	public static <E extends Object> Boolean equals(E a,E b){
		return a.equals(b);
	}
}


2、受限泛型:<T extends GemotriObject>:将E指定为GemotriObject的子类型

public class UnBounded {

	public static void main(String[] args) {
      Rectangle rectangle = new Rectangle(3.0,4.0);
      Rectangle rectangle2 = new Rectangle(3.0, 4.0);
      Circle circle = new Circle(2.0);
      System.out.println(equalArea(rectangle, circle));
      System.out.println(equalArea(rectangle, rectangle2));
	}
    
	/**受限泛型*/
	public static <E extends GeometricObject> boolean equalArea(E e1,E e2) {
		return e1.getArea() == e2.getArea();
	}
} 

其中Circle和Rectangle都是接口GeometricObject的实现类

注意:定义一个方法为泛型类型,要将泛型类型放在方法返回类型之前

案例:对一个对象数组进行排序

package fanxin;


public class GenericSort {
    public static void main(String[] args) {
    	Integer[] integers = {new Integer(2),new Integer(1),new Integer(3)};
    	Double[] doubles = {new Double(2.0),new Double(1.0),new Double(2.0)};
    	Character[] characters = {new Character('a'),new Character('c'),new Character('b')};
    	String[] strings = {"hello","you","world"};
    	
    	Sort(integers);
    	Sort(doubles);
    	Sort(characters);
    	Sort(strings);
    	
    	System.out.print("Sorted Integer objects:");
    	print(integers);
    	System.out.print("Sorted Double objects:");
    	print(doubles);
    	System.out.print("Sorted Character objects:");
    	print(characters);
    	System.out.print("Sorted String objects:");
    	print(strings);
    }
    
    /**泛型排序函数*/
    public static <E extends Comparable<E>> void Sort(E[] list) {
    	E currentMin;
    	int currentMinIndex;
    	
    	for(int i = 0; i < list.length; i++) {
    		currentMin = list[i];
    		currentMinIndex = i;
    		for(int j= i + 1; j < list.length; j++) {
    			if(currentMin.compareTo(list[j]) > 0) {
    				currentMin = list[j];
    				currentMinIndex = j;
    			}
    		}
    		
    		if(currentMinIndex != i) {
    			list[currentMinIndex] = list[i];
    			list[i] = currentMin;
    		}
    	}
    }
    
    /**打印*/
    public static void print(Object[] list) {
    	for(int i =0 ;i < list.length; i++) {
    		System.out.print(list[i] + " ");
    	}
    	System.out.println();
    }
}


/*输出结果
Sorted Integer objects:1 2 3 
Sorted Double objects:1.0 2.0 2.0 
Sorted Character objects:a b c 
Sorted String objects:hello world you */

其中要求这些对象都是Comparable接口的实例!


二、泛型类、泛型接口:

案例:模拟栈的实现:

package fanxin;

import java.util.ArrayList;

public class GenericStack<E> {
   private ArrayList<E> list = new ArrayList<>();
   
   public int getSize() {
	   return list.size();
   }
   
   //返回栈顶元素
   public E peek() {
	   return list.get(list.size()-1);
   }
   
   public void push(E o) { 
	   list.add(o);
   }
   
   public E pop() {
	   E o = list.get(list.size() - 1);
	   list.remove(o);
	   return o;
   }
   
   public boolean isEmpty() {
	   return list.isEmpty();
   }

   @Override
   public String toString() {
	   return "stack:"+list.toString();
   }
   
   
   public static void main(String[] args) {
	   GenericStack<String> stack = new GenericStack<>();
	   stack.push("joe");
	   stack.push("hello");
	   stack.push("world");
   }
}

注意:泛型类可能有多个参数时,所有参数都应放在尖括号内,并用逗号隔开<E1,E2,E3>