(1)在使用Arrays.asList轉成的List時同樣要注意,Arrays.asList返回類型為Arrays類內部定義的私有類ArrayList,並且繼承與AbstractList,翻閱AbstractList源碼是可以發現,是不支持add和remove操作的,也就是說Arrays.asList返回的List是個固定大小的List。
(2)在使用com.google.common.collect提供的jar包Lists類的Lists.newArrayList方法時,有相同的問題,如果傳入基本類型數組,也無法轉化成一個正常的List,這一點跟ArrayList結果是一致的。但是對象數組進行轉化時,有一點不同,轉成的List是支持add和remove操作的。
昨天在開發中遇到一個場景,調用RPC,拿到返回結果(int[]數組),使用jackSon序列化為Json對象時,發現一個詭異的現象,在使用Lists.newArrayList和Arrays.asList將數組轉為List時,轉出來的對象並不是與原數組對應的一個List,二十一個很詭異的對象。后來研究一下JDK,發現了陷阱所在。
首先看一下Arrays.asList這個方法,這個方法可以將數組轉成list,是JDK中java.util包中Arrays類的靜態方法。
public class ArraysTest { private static void asListTest(){ String stringArray[]={"aa","bb","cc"}; List<String> sList= Arrays.asList(stringArray); for(String str:sList){//能遍歷出各個元素 System.out.println(str); } System.out.println(sList.size()); System.out.println("- - - - - - - - - - -"); int intArray[]={11,22,33}; List intList=Arrays.asList(intArray); for(Object o:intList){//就一個元素 System.out.println(o.toString()); } System.out.println("- - - - - - - - - - -"); Integer integerArray[]={11,22,33}; List<Integer> objList=Arrays.asList(integerArray); //數組里的每一個元素都是作為list中的一個元素 for(int a:objList){ System.out.println(a); } System.out.println("- - - - - - - - - - -"); } public static void main(String[] args){ asListTest(); } }
結果如下:
Connected to the target VM, address: '127.0.0.1:12064', transport: 'socket' aa bb cc 3 - - - - - - - - - - - [I@2db0f6b2 - - - - - - - - - - - 11 22 33 - - - - - - - - - - - Disconnected from the target VM, address: '127.0.0.1:12064', transport: 'socket' Process finished with exit code 0
當基本類型數組使用Arrays.asList方法轉List時,並不能轉成正常的List,隨后我看了一下jdk源碼,看到問題所在
public static <T> List<T> asList(T... a) { return new ArrayList<>(a); } 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) { a = Objects.requireNonNull(array); } }
基本類型int不是對象類型,在使用Arrays.asList時,做泛型擦除時,將int[]當做對象類型,所以轉成一個只有一個元素的List。在使用Arrays.asList轉成的List時同樣要注意,Arrays.asList返回類型為Arrays類內部定義的私有類ArrayList,並且繼承與AbstractList,翻閱AbstractList源碼是可以發現,是不支持add和remove操作的,也就是說Arrays.asList返回的List是個固定大小的List。
如果希望轉過后的list可以支持add和remove操作,可使用如下方法:
/*方法一*/ ArrayList<Integer> copyArrays=new ArrayList<>(Arrays.asList(integerArray)); /*方法二*/ List<Integer> integerList = new ArrayList<>(); Collections.addAll(integerList, integerArray);
如果想把一個基本類型數組轉化為List,可使用如下方法:
Arrays.asList(ArrayUtils.toObject(intArray));
在使用com.google.common.collect提供的jar包Lists類的Lists.newArrayList方法時,有相同的問題,如果傳入基本類型數組,也無法轉化成一個正常的List,這一點跟ArrayList結果是一致的。但是對象數組進行轉化時,有一點不同,轉成的List是支持add和remove操作的。