为什么要使用泛型?优点在哪里?
使用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>