asList和ArrayList不得不說的故事


asList和ArrayList不得不說的故事

簡介

提到集合類,ArrayList應該是用到的非常多的類了。這裏的ArrayList是java.util.ArrayList,通常我們怎麼創建ArrayList呢?

創建ArrayList

看下下面的例子:

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

上面的方法創建了一個ArrayList,如果我們需要向其中添加元素的話,需要再調用add方法。

通常我們會使用一種更加簡潔的辦法來創建List:

    @Test
    public void testAsList(){
        List<String> names = Arrays.asList("alice", "bob", "jack");
        names.add("mark");

    }

看下asList方法的定義:

    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

很好,使用Arrays.asList,我們可以方便的創建ArrayList。

運行下上面的例子,奇怪的事情發生了,上面的例子居然拋出了UnsupportedOperationException異常。

java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at com.flydean.AsListUsage.testAsList(AsListUsage.java:18)

UnsupportedOperationException

先講一下這個異常,UnsupportedOperationException是一個運行時異常,通常用在某些類中並沒有實現接口的某些方法。

爲什麼上面的ArrayList調用add方法會拋異常呢?

asList

我們再來詳細的看一下Arrays.asList方法中返回的ArrayList:

private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable

可以看到,Arrays.asList返回的ArrayList是Arrays類中的一個內部類,並不是java.util.ArrayList。

這個類繼承自AbstractList,在AbstractList中add方法是這樣定義的:

    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

好了,我們的問題得到了解決。

轉換

我們使用Arrays.asList得到ArrayList之後,能不能將其轉換成爲java.util.ArrayList呢?答案是肯定的。

我們看下下面的例子:

    @Test
    public void testList(){
        List<String> names = new ArrayList<>(Arrays.asList("alice", "bob", "jack"));
        names.add("mark");
    }

上面的例子可以正常執行。

總結

在java中有很多同樣名字的類,我們需要弄清楚他們到底是什麼,不要混淆了。

本文的例子https://github.com/ddean2009/learn-java-collections

歡迎關注我的公衆號:程序那些事,更多精彩等着您!
更多內容請訪問 www.flydean.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章