学习笔记 --泛型

    技术2024-07-30  69

    泛型(Generic)

    JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。例如:

    ArrayList list = new ArrayList();

    list.add("abc");

    Integer num = (Integer) list.get(0);  //运行时会出错,但编码时发现不了

          

           使用泛型后的代码

           ArrayList<String> list = new ArrayList<String>();

           list.add(“abc”);

           Integer num = list.get(0);//写程序时则报错

     

    JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)

    注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为擦除

    泛形的基本术语:

    ArrayList<E>为例:<>念着typeof

             ArrayList<E>中的E称为类型参数变量

             ArrayList<Integer>中的Integer称为实际类型参数

             整个称为ArrayList<E>泛型类型

             整个ArrayList<Integer>称为参数化的类型ParameterizedType

     

     

     

    //使用迭代器迭代泛形集合中的元素。

    @Test

           public void test1(){

                 

                  List<String> list = new ArrayList<String>();

                  list.add("aaa");list.add("bbb");list.add("ccc");

                 

                  Iterator<String> it = list.iterator();

                  while(it.hasNext()){

                         String value = it.next();

                         System.out.println(value);

                  }

           }

     

     

     

     

    //存取HashMap中的元素

     

           public void test2(){

                  Map<Integer,String> map = new HashMap<Integer,String>();

                  map.put(1, "aaa");

                  map.put(2, "bbb");

                  map.put(3, "ccc");

                 

                  //1.keyset

                  Set<Integer> set = map.keySet();

                  Iterator<Integer> it = set.iterator();

                  while(it.hasNext()){

                         Integer key = it.next();

                         String value = map.get(key);

                         System.out.println(key + "=" + value);

                  }

                 

                  //2.entryset

                  Set<Map.Entry<Integer, String>> set1 = map.entrySet();

                  Iterator<Map.Entry<Integer, String>> it1 = set1.iterator();

                  while(it1.hasNext()){

                         Map.Entry<Integer, String> me = it1.next();

                         int key = me.getKey();

                         String value = me.getValue();

                         System.out.println(key + "=" + value);

                  }

                 

                  //3.foreach

                  for(Map.Entry<Integer, String> me : map.entrySet()){

                         int key = me.getKey();

                         String value = me.getValue();

                         System.out.println(key + "=" + value);

                  }

                 

           }

     

     

     

     

     

     

     

    自定义泛形——泛型方法

    l       Java程序中的普通方法、构造方法和静态方法中都可以使用泛型。方法使用泛形前,必须对泛形进行声明,语法:<T> T可以是任意字母,但通常必须要大写。<T>通常需放在方法的返回值声明之前。例如:

                  public static <T> void doxx(T t);

    l       注意:

             只有对象类型才能作为泛型方法的实际参数。

             在泛型中可以同时有多个类型,例如:

                  public static <K,V> V getValue(K key) { return map.get(key);}

     

    //自定义带有泛形的方法

    public class Demo4 {

           public <T> void run(T t){    

           }

           public <T,E> E eat(T t){

                  return null;

           }    

    }

     

    //定义带有泛形的类

    class Demo41<T> {

           public  void run(T t){

           }

           public <E> E eat(T t){

                  return null;

           }

          

    }

     

    //声明泛形的注意事项:类上面声明的泛形只对类的非静态态成员有效,类上面的静态成员使用泛形,它们需单独声明

    class Demo42<T> {

           public  void run(T t){  

           }

           public static <T> void eat(T t){    

           }

    }

     

    //编写一个泛形方法,实现数组元素的交换

           public <T> void swap(T arr[],int index1,int index2){

                  T temp = arr[index1];

                  arr[index1] = arr[index2];

                  arr[index2] = temp;

           }

    @Test

           public void testSwap(){

                  Demo5 d = new Demo5();

                  Integer arr[] = {1,2,3};

                  d.swap(arr, 0, 2);

           }

          

          

          

    //编写一个泛形方法,接收一个任意数组,并颠倒数组中的所有元素

           public <T> void reverse(T arr[]){

                 

                  int start = 0;

                  int end = arr.length-1;

                 

                  for(;;){

                         if(start>=end){

                                break;

                         }

                         T temp = arr[start];

                         arr[start] = arr[end];

                         arr[end] = temp;

                        

                        

                         start++;

                         end--;

                  }

           }

    @Test

           public void testReverse(){

                  Demo5 d = new Demo5();

                  Integer arr[] = {1,2,3};

                  d.reverse(arr);

                  System.out.println(Arrays.asList(arr));

           }

     

    泛型的高级应用——有限制的通配符

    l       限定通配符的上边界:

    正确:Vector<? extends Number> x = new Vector<Integer>();

    错误:Vector<? extends Number> x = new Vector<String>();

    l       限定通配符的下边界:

    正确:Vector<? super Integer> x = new Vector<Number>();

    错误:Vector<? super Integer> x = new Vector<Byte>();

     

    最新回复(0)