千萬不要這樣使用Arrays.asList !

做者:flyhero | 微信公衆號:碼上實戰(ID:Push-Code)java

使用Arrays.asList()的緣由無非是想將數組或一些元素轉爲集合,而你獲得的集合並不必定是你想要的那個集合。程序員

而一開始asList的設計時用於打印數組而設計的,但jdk1.5開始,有了另外一個比較更方便的打印函數Arrays.toString(),因而打印再也不使用asList(),而asList()恰巧可用於將數組轉爲集合。面試

1、錯誤用法

若是你這樣使用過,那你可要注意了。後端

一、錯誤一

將基本類型數組做爲asList的參數數組

猜一下輸出結果?性能優化

二、錯誤二

將數組做爲asList參數後,修改數組或List微信

猜一下輸出結果?網絡

三、錯誤三

數組轉換爲集合後,進行增刪元素多線程

猜一下輸出結果?分佈式

你是否是覺得上面 👆那個 list 是 java.util.ArrayList ?

答案很肯定:NO !

2、深刻探究

咱們經過asList()源碼可發現其緣由,但爲了更直觀,咱們先經過IDEA debug來看看結果。

其實它返回的是  java.util.Arrays.ArrayList,這個傢伙是誰呢?

請看下源碼:

但它和ArrayList貌似很像唉!有什麼不一樣嗎?

3、不一樣之處

Arrays.ArrayList 是工具類 Arrays 的一個內部靜態類,它沒有徹底實現List的方法,而 ArrayList直接實現了List 接口,實現了List全部方法。

  • 長度不一樣 和 實現的方法不一樣

    Arrays.ArrayList是一個定長集合,由於它沒有重寫add,remove方法,因此一旦初始化元素後,集合的size就是不可變的。

  • 參數賦值方式不一樣

Arrays.ArrayList將外部數組的引用直接經過「=」賦予內部的泛型數組,因此本質指向同一個數組。

ArrayList是將其餘集合轉爲數組後copy到本身內部的數組的。

4、揭曉答案

一、錯誤一

因爲Arrays.ArrayList參數爲可變長泛型,而基本類型是沒法泛型化的,因此它把int[] arr數組當成了一個泛型對象,因此集合中最終只有一個元素arr。

二、錯誤二

因爲asList產生的集合元素是直接引用做爲參數的數組,因此當外部數組或集合改變時,數組和集合會同步變化,這在平時咱們編碼時可能產生莫名的問題。

三、錯誤三

因爲asList產生的集合並無重寫add,remove等方法,因此它會調用父類AbstractList的方法,而父類的方法中拋出的倒是異常信息。

5、支持基礎類型的方式

一、若是使用Spring

二、若是使用Java 8

6、數組轉ArrayList

一、遍歷轉換

顯然這種方式不夠優雅!反正我不肯意使用。

二、使用工具類

上面方案不夠優雅,那麼這種相對來講優雅一些。

你覺得這種還不錯? too young too simple! addAll()方法的實現就是用的上面遍歷的方式。

三、若是使用Java 8

既能夠用於基本類型也能夠返回想要的集合。

四、兩個集合類結合

將Arrays.asList返回的集合做爲ArrayList的構造參數

7、最後

勿以點小而不聞!體現程序素養或許就在這些小地方,不要給本身或別人留坑。那麼這個知識點,你get到了嗎?

熱門內容:

一、2019年程序員高考真題新鮮出爐!看看你能得幾分!

二、從開源小白到 Apache Member,個人成長之路!

三、GitHub 五萬星登頂,命令行的藝術!

四、19 個強大、有趣、好玩、又裝B的 Linux 命令!

五、如何正確訪問Redis中的海量數據?服務纔不會掛掉!

六、爲何有些大公司技術弱爆了?

七、必會的55個Java性能優化細節!一網打盡!

八、面試題:InnoDB中一棵B+樹能存多少行數據?

【視頻福利】2T免費學習視頻,搜索或掃描上述二維碼關注微信公衆號:Java後端技術(ID: JavaITWork),和20萬人一塊兒學Java!回覆:1024,便可免費獲取!內含SSM、Spring全家桶、微服務、MySQL、MyCat、集羣、分佈式、中間件、Linux、網絡、多線程,Jenkins、Nexus、Docker、ELK等等免費學習視頻,持續更新!

相關文章
相關標籤/搜索