java.util.Arrays.asList 问题

来源:互联网 发布:自学苏绣知乎 编辑:程序博客网 时间:2024/05/21 02:49

From: http://www.cnblogs.com/zolra/archive/2011/03/02/1969235.html

 

JDK 1.4对java.util.Arrays.asList的定义,函数参数是Object[]。所以,在1.4中asList()并不支持基本类型的数组作参数。

 JDK 1.5中,java.util.Arrays.asList的定义,函数参数是Varargs, 采用了泛型实现。同时由于autoboxing的支持,使得可以支持对象数组以及基本类型数组。

 不过在使用时,当传入基本数据类型的数组时,会出现小问题,会把传入的数组整个当作返回的List中的第一个元素,例如:

 

[java] view plaincopy
  1. import java.util.Arrays;  
  2.   
  3. public class TestList {  
  4.     public static void main(String[] args) {  
  5.         int[] a1 = new int[] { 123 };  
  6.         String[] a2 = new String[] { "a""b""c" };  
  7.         System.out.println(Arrays.asList(a1));  
  8.         System.out.println(Arrays.asList(a2));  
  9.     }  
  10. }  


 

打印结果如下:

 [[I@3bb2b8]
[a, b, c]

 

下面说说Arrays.asList()的返回值:

JDK文档是这么说的:
public static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表。(对返回列表的更改会“直接写”到数组。)此方法同 Collection.toArray() 一起,充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。返回的列表是可序列化的,并且实现了 RandomAccess。此方法还提供了一个创建固定长度的列表的便捷方法,该列表被初始化为包含多个元素: List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");

我们都知道,List的一个典型的特性就是其长度是可变的,我们可以很方便地对它进行插入和删除元素的操作,这是它与数组所存在的一个很大的区别,后者的长度是固定的,而且我们不能从数组中删除元素,只能修改元素的值。利用Arrays.asList(array)将返回一个List,然而这个返回的List并不支持add和remove的操作。

这是什么原因呢?

Arrays.asList源码:

 

[java] view plaincopy
  1. public static <T> List<T> asList(T... a) {  
  2.    return new ArrayList<T>(a);  
  3.  }  


 

这里的ArrayList并不是java.util.ArrayList,而是Arrays的内部类:


[java] view plaincopy
  1. /** 
  2.      * @serial include 
  3.      */  
  4.     private static class ArrayList<E> extends AbstractList<E> implements  
  5.             RandomAccess, java.io.Serializable {  
  6.         private static final long serialVersionUID = -2764017481108945198L;  
  7.   
  8.         private final E[] a;  
  9.   
  10.         ArrayList(E[] array) {  
  11.             if (array == null)  
  12.                 throw new NullPointerException();  
  13.             a = array;  
  14.         }  
  15.   
  16.         public int size() {  
  17.             return a.length;  
  18.         }  
  19.   
  20.         public Object[] toArray() {  
  21.             return a.clone();  
  22.         }  
  23.   
  24.         public <T> T[] toArray(T[] a) {  
  25.             int size = size();  
  26.             if (a.length < size)  
  27.                 return Arrays.copyOf(this.a, size, (Class<? extends T[]>) a  
  28.                         .getClass());  
  29.             System.arraycopy(this.a, 0, a, 0, size);  
  30.             if (a.length > size)  
  31.                 a[size] = null;  
  32.             return a;  
  33.         }  
  34.   
  35.         public E get(int index) {  
  36.             return a[index];  
  37.         }  
  38.   
  39.         public E set(int index, E element) {  
  40.             E oldValue = a[index];  
  41.             a[index] = element;  
  42.             return oldValue;  
  43.         }  
  44.   
  45.         public int indexOf(Object o) {  
  46.             if (o == null) {  
  47.                 for (int i = 0; i < a.length; i++)  
  48.                     if (a[i] == null)  
  49.                         return i;  
  50.             } else {  
  51.                 for (int i = 0; i < a.length; i++)  
  52.                     if (o.equals(a[i]))  
  53.                         return i;  
  54.             }  
  55.             return -1;  
  56.         }  
  57.   
  58.         public boolean contains(Object o) {  
  59.             return indexOf(o) != -1;  
  60.         }  
  61.     }  


 

 

我们可以看到该内部类继承的是AbstractList,下面是AbstractList的add和remove方法源码:

[java] view plaincopy
  1. public boolean add(E e) {  
  2.      add(size(), e);  
  3.     return true;  
  4.  }  
  5.   
  6.  public void add(int index, E element) {  
  7.      throw new UnsupportedOperationException();  
  8. }  
  9.   
  10.  public E remove(int index) {  
  11.      throw new UnsupportedOperationException();  
  12.  }  



 

 

所以,当我们对Arrays.asList返回的List进行添加或删除时将会报 java.lang.UnsupportedOperationException 异常。

原创粉丝点击