天天看點

Arrays.asList()使用中遇到的問題

title: Arrays.asList()使用中遇到的問題

date: 2020-04-17 14:08:37

categories:java

tags:

概述

Arrays

是java.util包中提供的工具類,主要用于對數組進行各種操作

Arrays.asList()

是該類中提供的一個靜态方法,根據源碼注釋,作用為基于特定數組傳回一個固定大小的清單

Returns a fixed-size list backed by the specified array

問題

運作如下代碼時出現異常:

String[] strs={"str1","str2","str3","str4"};

List<String> arr=Arrays.asList(strs);
        
arr.add("str5");//抛出異常java.lang.UnsupportedOperationException
arr.remove("str1");//抛出異常java.lang.UnsupportedOperationException

System.out.println(arr);
           

這裡通過Arrays.asList()将String數組轉化為List,但對List進行add和remove操作時卻報異常

UnsupportedOperationException

,這是為啥呢,為什麼操作不支援呢?

根據上述概述,該方法傳回一個

fixed-size

,即大小不能改變的清單,該方法的源碼很簡單,

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

由源碼可知,該方法傳回一個

ArrayList

,那為啥

ArrayList

就不支援add和remove操作了呢?

原來,這裡的

ArrayList

并不是java.util包中的集合類

ArrayList

,而是在

Arrays

類中自定義的一個内部類,其類的定義源碼就在

asList()

方法源碼下;

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-SlsXF0hb-1589178740353)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420144009.png)]

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-8x6YuRxF-1589178740354)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420144148.png)]

(話說為啥不換個名)

該内部類源碼為

private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
    //内部源碼省略
    ....
    ....
    }
           

可以看到該類繼承了

AbstractList

類,并實作了

RandomAccess

Serializable

接口;該類源碼中沒有定義add,remove方法

進一步檢視

AbstractList

類源碼

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
    //部分源碼省略
    ...
    ...
    
 	public boolean add(E e) {
        add(size(), e);
        return true;
    }
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }
     public E remove(int index) {
        throw new UnsupportedOperationException();
    }
    
    //部分源碼省略
    ...
    ...
}
           

可以看到,該類繼承

AbstraceCollection

類并實作

List

接口,執行add,remove操作時均抛出

UnsupportedOperationException

異常;

事實上,檢視

AbstraceList

類其餘源碼可以看到,其中set方法也抛出

UnsupportedOperationException

異常,但ArrayList内部類重寫了set方法,是以可以執行set操作

注意:

  1. 執行set操作時,如下代碼,分别對數組和由數組轉化的List集合元素進行修改
public static void main(String[] args) {
     String[] strs={"str1","str2","str3","str4"};
     List<String> list=Arrays.asList(strs);
     
     System.out.println(Arrays.toString(strs));
     System.out.println(list);
     
     strs[0]="str1_new";//對strs進行修改
     list.set(1,"str2_new");//對list進行修改
     
     System.out.println(Arrays.toString(strs));
     System.out.println(list);
 }
           

結果如下:

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-sSor2LLL-1589178740356)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420151851.png)]

發現對數組進行的修改影響到了集合,對于集合進行的修改也影響到了數組;

這是因為

asList()

轉化得到的集合元素直接引用了數組,數組和集合的變化會同步,這同時可能會導緻一些編碼上的問題

  1. asList()

    方法不可操作基本資料類型;因為由于通過new建立一個Arrays.ArrayList時,其參數為可變長泛型,而基本類型是無法泛型化的