Arrays.asList的坑

簡(jiǎn)介:

將一個(gè)數(shù)組轉(zhuǎn)換為 List 以便進(jìn)行更豐富的操作

坑一: 將原生數(shù)據(jù)類型數(shù)據(jù)的數(shù)組作為參數(shù)

public class Main {
    public static void main(String[] args) {
      int[] test = new int[]{1,2,3,4};
      List list = Arrays.asList(test);
        System.out.println(list.size());
        System.out.println(list);
/*
1
[[I@45ee12a7]
*/
    }
}

嘗試使用IDEA自動(dòng)修復(fù)看看它傳入的類型:居然是int[]



也就是說(shuō)T是數(shù)組元素的 class
如果你對(duì)反射技術(shù)比較了解的話,那么 class 的含義想必是不言自明。我們知道任何類型的對(duì)象都有一個(gè) class 屬性,這個(gè)屬性代表了這個(gè)類型本身。原生數(shù)據(jù)類型,比如 int,short,long等,是沒(méi)有這個(gè)屬性的,具有 class 屬性的是它們所對(duì)應(yīng)的包裝類 Integer,Short,Long。
??因此,這個(gè)錯(cuò)誤產(chǎn)生的原因可解釋為:asList 方法的參數(shù)必須是對(duì)象或者對(duì)象數(shù)組,而原生數(shù)據(jù)類型不是對(duì)象——這也正是包裝類出現(xiàn)的一個(gè)主要原因。當(dāng)傳入一個(gè)原生數(shù)據(jù)類型數(shù)組時(shí),asList 的真正得到的參數(shù)就不是數(shù)組中的元素,而是數(shù)組對(duì)象本身!此時(shí)List 的唯一元素就是這個(gè)數(shù)組。
解決方案:使用包裝類數(shù)組或使用流轉(zhuǎn)換為L(zhǎng)ist

1.
public class Main {
    public static void main(String[] args) {
      Integer[] test = new Integer[]{1,2,3,4};
      List list = Arrays.asList(test);
        System.out.println(list.size());
        System.out.println(list);
/*
4
[1, 2, 3, 4]
*/
    }
}

2.
public class Main {
    public static void main(String[] args) {
      int[] test = new int[]{1,2,3,4};
//Java 8 新引入的 Stream 操作 要將一個(gè)原始類型流轉(zhuǎn)換成一個(gè)對(duì)象流,可以使用boxed方法
        List myList = Arrays.stream(test).boxed().collect(Collectors.toList());
        System.out.println(myList.size());
        System.out.println(myList);
/*
4
[1, 2, 3, 4]
*/
    }
}

坑二:試圖修改 List 的大小

public class Main {
    public static void main(String[] args) {
      Integer[] test = new Integer[]{1,2,3,4};
      List list = Arrays.asList(test);
      Integer a = new Integer(1);
      list.add(a);
//Exception in thread "main" java.lang.UnsupportedOperationException
    }
}

直接報(bào)錯(cuò)
向 list 添加新元素是不被允許的;
如果試圖從 myList 中刪除元素,也會(huì)拋出相同的異常。為什么會(huì)如此?
官方指出有一句話:
Arrays.asList返回一個(gè)由指定數(shù)組生成的固定大小的 List。
查看相關(guān)的源碼


方法中的的確確生成了一個(gè) ArrayList 再點(diǎn)進(jìn)去看

有一個(gè)被聲明為 final 的數(shù)組 a ,所有傳入的元素都會(huì)被保存在這個(gè)數(shù)組 a 中。到此,謎底又揭曉了: asList 方法返回的確實(shí)是一個(gè) ArrayList ,但這個(gè) ArrayList 并不是 java.util.ArrayList ,而是 java.util.Arrays 的一個(gè)內(nèi)部類。這個(gè)內(nèi)部類用一個(gè) final 數(shù)組來(lái)保存元素,因此用 asList 方法產(chǎn)生的 ArrayList 是不可修改大小的。這里記住最后是一個(gè)final數(shù)組保存的元素
與下面final修飾區(qū)分

final List<Integer> list1 = new ArrayList<>();
list1.add(new Integer(1));
list1.add(new Integer(2));
System.out.println(list1);
//[1,2]

解決方案:創(chuàng)建一個(gè)真正的 ArrayList

Integer[] test = new Integer[]{1,2,3,4};
List list = new ArrayList(Arrays.asList(test));
list.add(new Integer(5));
System.out.println(list);
//[1, 2, 3, 4, 5]

參考文章
http://www.itdecent.cn/p/2b113f487e5e

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 碰到這樣一個(gè)問(wèn)題使用Arrays.asList返回的ArrayList無(wú)法進(jìn)行add,remove操作,測(cè)試一下原...
    wtmxx閱讀 314評(píng)論 0 1
  • 對(duì)象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法,而不是構(gòu)造函數(shù)創(chuàng)建對(duì)象:僅僅是創(chuàng)建對(duì)象的方法,并非Fa...
    孫小磊閱讀 2,182評(píng)論 0 3
  • 第十一章 持有對(duì)象 Java實(shí)用類庫(kù)還提供了一套相當(dāng)完整的容器類來(lái)解決這個(gè)問(wèn)題,其中基本的類型是List、Set、...
    Lisy_閱讀 908評(píng)論 0 1
  • 在網(wǎng)上發(fā)現(xiàn)一篇講解 Arrays.asList 用法的好文章:Java Array to List Example...
    maxwellhertz閱讀 79,688評(píng)論 18 78
  • 傳送門(mén) 解讀阿里Java開(kāi)發(fā)手冊(cè)(v1.1.1) - 異常日志 前言 阿里Java開(kāi)發(fā)手冊(cè)談不上圣經(jīng),但確實(shí)是大量...
    kelgon閱讀 4,461評(píng)論 4 50

友情鏈接更多精彩內(nèi)容