日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

正確認(rèn)識(shí)Arrays.asList方法

 行者花雕 2020-01-10

Arrays工具類提供了一個(gè)方法asList, 使用該方法可以將一個(gè)變長(zhǎng)參數(shù)或者數(shù)組轉(zhuǎn)換成List 

其源代碼如下:

    /**
     * Returns a fixed-size list backed by the specified array.  (Changes to
     * the returned list "write through" to the array.)  This method acts
     * as bridge between array-based and collection-based APIs, in
     * combination with {@link Collection#toArray}.  The returned list is
     * serializable and implements {@link RandomAccess}.
     *
     * <p>This method also provides a convenient way to create a fixed-size
     * list initialized to contain several elements:
     * <pre>
     *     List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
     * </pre>
     *
     * @param a the array by which the list will be backed
     * @return a list view of the specified array
     */
    @SafeVarargs
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

 

問(wèn)題發(fā)現(xiàn)

根據(jù)上述方法的描述,我們先來(lái)編寫幾個(gè)例子:

/**
 * @author wangmengjun
 *
 */
public class ArrayExample {
    
    public static void main(String[] args) {
        
        /**使用變長(zhǎng)參數(shù)*/
        List<String> array1 = Arrays.asList("Welcome", "to","Java", "world");
        System.out.println(array1);
        
        /**使用數(shù)組*/
        List<String> array2 =  Arrays.asList(new String[] {"Welcome", "to","Java", "world"});
        System.out.println(array2);
    }

}

 

運(yùn)行上述程序,輸出如下內(nèi)容。

[Welcome, to, Java, world]
[Welcome, to, Java, world]

 

心血來(lái)潮,突然想在創(chuàng)建的列表中添加一個(gè)字符串“Cool~~~”,  走一個(gè)。

        /**使用變長(zhǎng)參數(shù)*/
        List<String> array1 = Arrays.asList("Welcome", "to","Java", "world");
        array1.add("Cool~~~");

結(jié)果,遇到一個(gè)UnsupportedOperationException異常:

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(Unknown Source)
	at java.util.AbstractList.add(Unknown Source)
	at test.ArrayExample.main(ArrayExample.java:36)

不可思議,new ArrayList<>(a)產(chǎn)生的列表調(diào)用add方法,竟然遇到問(wèn)題。

原因查找

那么問(wèn)題來(lái)了,到底發(fā)生了什么事情?帶著疑問(wèn),去查看一下Arrays.asList中使用的ArrayList到底長(zhǎng)啥樣?

原來(lái)Arrays的asList方法使用的ArrayList類是一個(gè)內(nèi)部定義的類而不是java.util.ArrayList類。

其源代碼如下:


    /**
     * @serial include
     */
    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;

        ArrayList(E[] array) {
            if (array==null)
                throw new NullPointerException();
            a = array;
        }

        public int size() {
            return a.length;
        }

        public Object[] toArray() {
            return a.clone();
        }

        public <T> T[] toArray(T[] a) {
            int size = size();
            if (a.length < size)
                return Arrays.copyOf(this.a, size,
                                     (Class<? extends T[]>) a.getClass());
            System.arraycopy(this.a, 0, a, 0, size);
            if (a.length > size)
                a[size] = null;
            return a;
        }

        public E get(int index) {
            return a[index];
        }

        public E set(int index, E element) {
            E oldValue = a[index];
            a[index] = element;
            return oldValue;
        }

        public int indexOf(Object o) {
            if (o==null) {
                for (int i=0; i<a.length; i++)
                    if (a[i]==null)
                        return i;
            } else {
                for (int i=0; i<a.length; i++)
                    if (o.equals(a[i]))
                        return i;
            }
            return -1;
        }

        public boolean contains(Object o) {
            return indexOf(o) != -1;
        }
    }

 

從這個(gè)內(nèi)部類ArrayList的實(shí)現(xiàn)可以看出,它繼承了抽象類java.util.AbstractList<E>, 但是沒有重寫addremove方法,沒有給出具體的實(shí)現(xiàn)。

但是,默認(rèn)情況下,java.util.AbstractList類在add、set以及remove方法中,直接會(huì)拋出UnsupportedOperationException異常。AbstractList的部分源代碼如下:

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
    /**
     * Sole constructor.  (For invocation by subclass constructors, typically
     * implicit.)
     */
    protected AbstractList() {
    }

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

    /**
     * {@inheritDoc}
     *
     * <p>This implementation always throws an
     * {@code UnsupportedOperationException}.
     *
     * @throws UnsupportedOperationException {@inheritDoc}
     * @throws ClassCastException            {@inheritDoc}
     * @throws NullPointerException          {@inheritDoc}
     * @throws IllegalArgumentException      {@inheritDoc}
     * @throws IndexOutOfBoundsException     {@inheritDoc}
     */
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     *
     * <p>This implementation always throws an
     * {@code UnsupportedOperationException}.
     *
     * @throws UnsupportedOperationException {@inheritDoc}
     * @throws IndexOutOfBoundsException     {@inheritDoc}
     */
    public E remove(int index) {
        throw new UnsupportedOperationException();
    }
}

 

正是因?yàn)?strong>java.util.Arrays類的內(nèi)部類ArrayList沒有重寫add和remove方法,所以,當(dāng)我們調(diào)用其add方法時(shí),其實(shí)就是調(diào)用了AbstractList類的add方法,結(jié)果就是直接拋出UnsupportedOperationException異常。

同理,在調(diào)用remove方法,或者調(diào)用與add、remove方法相關(guān)聯(lián)的其它方法(如addAll)同樣會(huì)遇到UnsupportedOperationException異常。

addAll的例子

/**
 * @author wangmengjun
 *
 */
public class ArrayExample {

    public static void main(String[] args) {

        /**使用變長(zhǎng)參數(shù)*/
        List<String> array1 = Arrays.asList("Welcome", "to", "Java", "world");
        array1.addAll(Arrays.asList("AAA", "BBB"));
    }

}

 

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(Unknown Source)
	at java.util.AbstractList.add(Unknown Source)
	at java.util.AbstractCollection.addAll(Unknown Source)
	at test.ArrayExample.main(ArrayExample.java:36)

 

set的例子:

/**
 * @author wangmengjun
 *
 */
public class ArrayExample {

    public static void main(String[] args) {

        /**使用變長(zhǎng)參數(shù)*/
        List<String> array1 = Arrays.asList("Welcome", "to", "Java", "world");
        System.out.println(array1);
        
        //將Java替換成hello
        array1.set(2, "hello");
        System.out.println(array1);
    }

}

正是由于Arrays的內(nèi)部類ArrayList重寫了set方法,所以上述程序能夠正常運(yùn)行,不會(huì)再拋出UnsupportedOperationException異常。

結(jié)果如下:

[Welcome, to, Java, world]
[Welcome, to, hello, world]

 

使用場(chǎng)景

從上述的例子和簡(jiǎn)單分析來(lái)看,Arrays工具類提供了一個(gè)方法asList, 使用該方法可以將一個(gè)變長(zhǎng)參數(shù)或者數(shù)組轉(zhuǎn)換成List 。

但是,生成的List的長(zhǎng)度是固定的;能夠進(jìn)行修改操作(比如,修改某個(gè)位置的元素);不能執(zhí)行影響長(zhǎng)度的操作(如add、remove等操作)。會(huì)拋出UnsupportedOperationException異常

Arrays.asList比較適合那些已經(jīng)有數(shù)組數(shù)據(jù)或者一些元素,而需要快速構(gòu)建一個(gè)List,只用于讀取操作,而不進(jìn)行添加或刪除操作的場(chǎng)景。

如果,想要根據(jù)已知數(shù)組數(shù)據(jù),快速獲取一個(gè)可進(jìn)行增刪改查的列表List,一個(gè)比較簡(jiǎn)單的方法如下:

重新使用java.util.ArrayList包裝一層。

/**
 * @author wangmengjun
 *
 */
public class ArrayExample {

    public static void main(String[] args) {

        /**使用變長(zhǎng)參數(shù)*/
        List<String> array1 = new ArrayList<>(Arrays.asList("Welcome", "to", "Java", "world"));
        System.out.println(array1);

        array1.add("Cool~~~");
        System.out.println(array1);

    }

}

結(jié)果如下:

[Welcome, to, Java, world]
[Welcome, to, Java, world, Cool~~~]

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多