javaweb-day03-7(基础加强-泛型)

来源:互联网 发布:crash撞车影评知乎 编辑:程序博客网 时间:2024/05/23 21:50

泛型(Generic) —泛形的作用

  • JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。
  • JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。
  • 注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
  • 泛形的基本术语,以ArrayList<E>为例:<>念着typeof
    • ArrayList<E>中的E称为类型参数变量
    • ArrayList<Integer>中的Integer称为实际类型参数
    • 整个称为ArrayList<E>泛型类型
    • 整个ArrayList<Integer>称为参数化的类型ParameterizedType

泛型典型应用

  • 使用迭代器迭代泛形集合中的元素。
  • 使用增强for循环迭代泛形集合中的元素。
  • 存取HashMap中的元素。
  • 使用泛形时的几个常见问题:
    • 使用泛形时,泛形类型须为引用类型,不能是基本数据类型
    • ArrayList<String>list = new ArrayList<Object>();   //这个代码是错误的,在存的时候凡是Object的子类对象都能存,在取的时候会把你存入的对象都当做Integer来处理,会出错。
    • ArrayList<Object>list = new ArrayList<String>();   //编译时报错
    • ArrayList<String>list = new ArrayList ();   //可以通过
    • ArrayList list= new ArrayList<String>();    //可以通过
  • 总结:一旦用上了泛型,两边的类型就应该保持一致,要么两边只用一边。

package cn.mengmei.generic;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import org.junit.Test;public class Demo1 {@Testpublic void test1(){List<Integer> list = new ArrayList<Integer>();list.add(1);int num = list.get(0);}@Testpublic void test2(){Map<String,Integer> map = new HashMap<String,Integer>();map.put("a", 30);map.put("b", 50);Set<Map.Entry<String, Integer>> set = map.entrySet();for(Map.Entry<String, Integer> me : set){String key = me.getKey();Integer value = me.getValue();System.out.println(key+"="+value);}}//一旦用上了泛型,两边的类型就应该保持一致,要么两边只用一边。@Testpublic void test3(){/*ArrayList<Integer> a = new ArrayList<Object>(); //编译时报错。ArrayList<Object> b = new ArrayList<Integer>(); //编译时报错。*///为了向以前版本的jdk兼容,为了新程序员可以调用老程序员写的方法,所以必须支持这种写法。ArrayList<String> c = new ArrayList();//例:List<Integer> l1 = t1();//为了初级程序员可以调用高级程序员写的方法,所以必须支持这种写法。ArrayList d = new ArrayList<String>();//例:List l2 = t2();}public List t1(){return new ArrayList();}public List<Integer> t2(){return new ArrayList<Integer>();}}

自定义泛形——泛型方法

  • Java程序中的普通方法、构造方法和静态方法中都可以使用泛型。方法使用泛形前,必须对泛形进行声明,语法:<T> ,T可以是任意字母,但通常必须要大写。<T>通常需放在方法的返回值声明之前。例如:
    •   public static <T> void doxx(T t);
  • 练习:
    • 编写一个泛形方法,实现数组元素的交换。
    • 编写一个泛形方法,接收一个任意数组,并颠倒数组中的所有元素。
  • 注意:
    • 只有对象类型才能作为泛型方法的实际参数。
    • 在泛型中可以同时有多个类型,例如:
      •   public static <K,V> V getValue(K key) { return map.get(key);}


package cn.mengmei.generic;import java.util.Arrays;public class Demo2 {public static void main(String[] args) {//原数组Integer[] arr = new Integer[]{1,2,3,4,5};System.out.println(Arrays.asList(arr));//交换位置1和位置2的两个元素swap(arr,1,2);System.out.println(Arrays.asList(arr));//从小到大排序sort(arr);System.out.println(Arrays.asList(arr));//原数组String[] arr1 = new String[]{"a","b","c","d","e"};System.out.println(Arrays.asList(arr1));//反转数组reverse(arr1);System.out.println(Arrays.asList(arr1));//从小到大排序sort(arr1);System.out.println(Arrays.asList(arr1));}//交换数组中的任意两个位置的元素public static <T> void swap(T[] arr, int pos1, int pos2){T temp = arr[pos1];arr[pos1] = arr[pos2];arr[pos2] = temp;}//颠倒数组中的所有元素public static <T> void reverse(T[] arr){for(int x=0,y=arr.length-1; x<y; x++,y--){swap(arr,x,y);}}//给数组元素由小到大排序public static <T extends Comparable<T>> void sort(T[] arr){for(int x=0; x<arr.length-1; x++){for(int y=x+1; y<arr.length; y++){if( ( arr[x].compareTo(arr[y]) ) > 0){swap(arr,x,y);}}}}}
运行结果:

[1, 2, 3, 4, 5]
[1, 3, 2, 4, 5]
[1, 2, 3, 4, 5]
[a, b, c, d, e]
[e, d, c, b, a]
[a, b, c, d, e]




package cn.mengmei.generic;//在类上定义的泛型,只对类的非静态成员有效。public class Demo3<T> {public void run(T t){}public void eat(T t){}//为什么在类上定义的泛型,只对类的非静态成员有效?//因为调用静态成员不需要new对象,没有new对象在类上定义的泛型T就没有指定。在调用这个方法的时候,这个T是啥别人就不知道。//为了编译通过,在方法上对T进行定义。public static <T> void test(T t){}}




基础加强还没讲完,要在二十几天的时候还要讲一天。



0 0
原创粉丝点击