Arrays.asList()有疑问吗?

时间:2011-01-25 10:09:10

标签: java collections

人们说asList方法将数组转换为列表而不是复制,因此'aList'中的每个更改都会反映为'a'。因此,在'aList'中添加新值是非法的,因为数组具有固定的大小。

但是,asList()方法返回ArrayList<T>。编译器如何将第3行与5区分开来。第3行给出了异常(UnsupportedOperationException)。

        String[] a = {"a","b","c","d"};//1
        List<String> aList =  Arrays.asList(a);//2
        aList.add("e");//3
        List<String> b = new ArrayList<String>();//4
        b.add("a");//5

8 个答案:

答案 0 :(得分:35)

您从Arrays.asList收到的此List实现是阵列上的特殊视图 - 您无法更改其大小。

Arrays.asList()的返回类型为java.util.Arrays.ArrayList,常常与java.util.ArrayList混淆。 Arrays.ArrayList只是将数组显示为列表

答案 1 :(得分:9)

Read again,Arrays.asList的类型是:

public static <T> List<T> asList(T... a)

明确指出asList返回一个实现接口java.util.List 的对象,它没有说它将返回类java.util.ArrayList 的实例

接下来,请注意List.add上的文档说:

  

布尔加法(E e)

     

将指定的元素追加到此列表的末尾(可选操作)

从技术上讲,每次使用类型为List(而不是ArrayList)的变量时,都应该始终注意这个方法可能会抛出UnsupportedOperationException。如果您确定只接收一个始终具有.add()语义的List实现,那么当您的假设失效时,您可以省略检查,以免出错。

答案 2 :(得分:5)

的Manoj,

Arrays.List的返回类型是List接口的一些未知内部实现,不是 java.util.ArrayList,因此您只能将它分配给List类型。

例如,如果将其分配给ArrayList,则会给出编译时错误 “类型不匹配:无法从List转换为ArrayList”

  ArrayList<String> aList =  Arrays.asList(a);// gives Compile time error

来自Javadoc“Arrays.asList返回由指定数组支持的固定大小列表。(对返回列表的更改”直写“到数组。)”这意味着您只提供了一个在运行时创建IMO的数组的列表视图,当然,您无法更改数组的大小,因此您也无法更改“Arrays.asList”的大小。

IMO Arrays.asList的内部实现具有所有可以改变数组大小的实现方法 -

void add(E e)
{
//some unknown code
throw(java.lang.UnsupportedOperationException);
}

因此,每当您尝试更改Array的大小时,它都会抛出UnsupportedOperationException。

如果你想通过使用这样的语法将一些新项添加到ArrayList,你可以通过创建Arraylist的子类(最好是使用ArrayList的匿名子类)来实现。你可以将Arrays.List的返回类型传递给ArrayList的构造函数(即public ArrayList(Collection c)),就像这样 -

List<String> girlFriends = new java.util.ArrayList<String>(Arrays.asList("Rose", "Leena", "Kim", "Tina"));
girlFriends.add("Sarah");

现在,您可以使用相同的语法轻松地将Sarah添加到GF列表中。

PS - 请选择这一个或另一个作为你的答案,因为已经解释了evrything。你的低接受率是非常令人沮丧的。

答案 3 :(得分:4)

asList()未返回java.util.ArrayList,它会返回java.util.Arrays$ArrayList。该类甚至不扩展java.util.ArrayList,因此它的行为可以(并且是)完全不同。

add()方法继承自java.util.AbstractList,默认情况下只会抛出UnsupportedOperationException

答案 4 :(得分:3)

这是一个例外而不是编译器错误。它在程序运行时抛出,而不是在编译时抛出。基本上,Arrays.asList将返回的实际类在throw UnsupporteOperationException方法中具有add()

更具体地说,Arrays.asList将返回Arrays类中定义的内部类,该内部类派生自AbstractList,并且不实现add方法。 add中的AbstractList方法实际上是抛出异常。

答案 5 :(得分:3)

您假设Arrays.asList()返回ArrayList,但事实并非如此。 Arrays.asList()返回未指定的List实现。该实现只会在每个不受支持的方法上抛出UnsupportedOperationException

答案 6 :(得分:1)

关键是

返回的List实现
List<String> aList =  Arrays.asList(a);

如果您查看Arrays中的源代码,您会看到它包含一个内部私有静态类ArrayList。这与java.util.ArrayList不同。

答案 7 :(得分:0)

asList返回固定大小的列表,因此您无法向其中添加新元素。因为它返回的列表实际上是它所创建的数组的“视图”(在你的情况下是'a'),所以你无法添加元素是有道理的 - 就像你不能添加元素一样数组。请参阅asList

的文档