【Java基礎】一個有意思的泛型方法Arrays.asList(T... a)


總結

  1. 利用Arrays.asList方法返回的List是不允許add和remove的,這種list的長度不可變,因為底層依然是寫數組。
  2. Arrays.asList的返回值是調用是傳入T類型的List,所以傳入啥,返回啥的列表
  3. T... a 底層本來就是轉換為T[] x的數組,所以如果傳入的T是數組,最后的底層參數是二維數組T[][] y.

Arrays.asList(T... a)方法的作用

將數組轉為集合的方法,返回的是List集合。和Collection的toArray對應,是數組和集合間相互轉換的兩個橋梁方法。asList接受的參數是T... a,這是一種可變參數的表示,這種可變參數底層其實會轉化為T[] x的形式,所以可以接受多個T類型的傳參。

Arrays.asList的示例代碼

下面寫了一段利用Arrays的asList方法將數組轉為List鏈表的測試方法:

import java.util.*;

/**
 * Created by lili on 15/11/13.
 */
public class Test {
    public static void main(String[] args) {
      
        List<Integer> integers = Arrays.asList(1, 2, 3, 4);

        int[] arr = new int[]{1,2,3,4};
        List<int[]> list0 = Arrays.asList(arr);
System.out.println(list0);
// list0.add(new int[]{111});//出錯 for(int[] a : list0){ System.out.println("mark1: "+a);//打印的是地址,Integer數組 for(int i : a){ System.out.println(i); } } System.out.println("----------------------"); // list0.set(0,11);//java.lang.ArrayStoreException: java.lang.Integer list0.set(0, new int[]{11}); List<Integer> list1 = Arrays.asList(1,2,3,4); System.out.println(list1); for(int a : list1){ System.out.println(a); } System.out.println("-----------------------"); list1.set(0, 11); // list1.add(11);//不支持add for(int a : list1){ System.out.println(a); } } }

上述代碼首先明顯的說明了一個問題:

  利用Arrays.asList方法返回的List是不允許add的,同時測試了remove也不可以,但是可以改為各個索引位置的值。隱含表示List長度不可變。

反編譯出來的結果是:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class Test {
    public Test() {
    }

    public static void main(String[] var0) {
        List var1 = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4)});
        int[] var2 = new int[]{1, 2, 3, 4};
        List var3 = Arrays.asList(new int[][]{var2});
        System.out.println(var3);
        Iterator var4 = var3.iterator();

        while(var4.hasNext()) {
            int[] var5 = (int[])var4.next();
            System.out.println("mark1: " + var5);
            int[] var6 = var5;
            int var7 = var5.length;

            for(int var8 = 0; var8 < var7; ++var8) {
                int var9 = var6[var8];
                System.out.println(var9);
            }
        }

        System.out.println("----------------------");
        var3.set(0, new int[]{11});
        List var10 = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4)});
        System.out.println(var10);
        Iterator var11 = var10.iterator();

        int var12;
        while(var11.hasNext()) {
            var12 = ((Integer)var11.next()).intValue();
            System.out.println(var12);
        }

        System.out.println("-----------------------");
        var10.set(0, Integer.valueOf(11));
        var11 = var10.iterator();

        while(var11.hasNext()) {
            var12 = ((Integer)var11.next()).intValue();
            System.out.println(var12);
        }

    }
}

上述反編譯出來的結果除了表明增強型for循環會轉變為Iterator外,更重要的是表明asList接受的傳參最后會轉變為數組:

  1. 如果直接在asList(int a,int b,int c,int d)中傳入一個個的值,最后轉換的是int[]{a,b,c,d},是一維數組。
  2. 如果傳入的本來是一個數組asList(int[] arr),最后轉換成一個二維數組,且該二維數組只有一個一維數組對象。

最終輸出結果:

[[I@27077aa7]
mark1: [I@27077aa7
1
2
3
4
----------------------
[1, 2, 3, 4]
1
2
3
4
-----------------------
11
2
3
4

Process finished with exit code 0

Arrays.asList的方法結構

在這里我們最大的疑惑是為啥返回的是List,卻不允許添加元素呢?下面看看asList的源碼:

 /**
     * 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&lt;String&gt; 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);
    }

asList是一個泛型方法,可以接受可變參數傳遞,而返回值是調用方法時傳入類型T的List,所以這里返回值是什么類型是一個重要的問題,在使用時要注意區分。

之所以不能修改,注釋的解釋是:返回一個受指定數組支持的固定大小的列表。(對返回列表的更改會“直接寫”到數組。)-->由於數組長度不可變,所以不可增刪


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM