List
的五種方法Java 中常常須要使用到 List,下面簡單介紹幾種常見的初始化方式。java
List
後使用 List.add
初始化List<String> stringList = new LinkedList<>();
stringList.add("a");
stringList.add("b");
stringList.add("c");
複製代碼
這是最常規的作法,用起來不太方便。數組
{{}}
雙括號語法List<String> stringList = new LinkedList<String>(){{
add("a");
add("b");
add("c");
}};
複製代碼
這種方式相對方便了一些。數據結構
外層的 {}
定義了一個 LinkedList 的匿名內部類。內層的 {}
的定義了一個實例初始化代碼塊。 這個代碼塊在初始化內部類時執行。因此這裏至關於定義了一個匿名內部類,並使用 add
添加元素來初始化。dom
這種方式有幾個缺點:spa
Arrays.asList
List<String> stringList = Arrays.asList("a", "b", "c");
複製代碼
這種方式使用了 java.util.Arrays
的靜態方法。寫法上比以前的兩種都更簡潔,也沒有構造匿名內部類的效率問題。code
但也有幾點須要注意:對象
Arrays.asList
返回的是 Arrays
的靜態內部類(靜態內部類不持有所在外部類的引用)。這個內部類繼承自 AbstractList
,實現了 RandomAccess
,內部使用了一個數組來存儲元素。可是不支持增刪元素。這點須要注意。若是隻是使用 Arrays.asList
來初始化常量,那麼這點就不算什麼問題了。繼承
Arrays.asList
的參數若是是基本類型的數組時,須要留意返回值可能和你預期的不一樣。int[] intArray = new int[]{1, 2, 3};
Integer[] integerArray = new Integer[]{1, 2, 3};
List<int[] > intArrayList = Arrays.asList(intArray);
List<Integer> integerList = Arrays.asList(integerArray);
List<Integer> integerList2 = Arrays.asList(1, 2, 3);
複製代碼
這裏 Arrays.asList(intArray)
的返回值是 List<int[]>
而不是 List<Integer>
。這一點也算不上問題,只是使用時須要留意。若是能在 Java 中作到儘可能使用 List 和 Integer,儘可能避免使用 int 等基本類型和 []
這種較爲底層的數據結構便可避免。內存
說點題外話: Java 終究仍是不能稱之爲徹底面向對象。畢竟保留了基本數據類型這種東西。誠然基本數據類型使用時比相應的封裝類型效率要更高。但也給使用過程當中帶來了一些困惑:到底該用基本類型,仍是封裝類型,何時該用這個,何時該用哪一個?雖然 Java 提供給了用戶更多的選擇,但有種將難題丟給用戶的感受。在我看來,Java 相比的 C++ 一個優勢,就是不少事情有了限制,有較爲明確清晰的定義,減小了模棱兩可,更容易理解。但基本數據類型這裏,感受仍是 Java 做爲一門改善了 C++ 缺點的語言留下的一些影子。get
雖然本文是在講初始化 List
,但這裏的 {{}}
雙括號語法一樣可用於初始化 Map
等其餘衆多類型。相對而言,Arrays.asList
就只能用於初始化 List
類型了。
Stream
(JDK8)List<String> list = Stream.of("a", "b", "c").collect(Collectors.toList());
複製代碼
使用了 JDK8 的 Stream 來初始化。 單純初始化 List,使用 Stream 有點大材小用了。
Lists
(JDK9)List<String> list = Lists.newArrayList("a", "b", "c");
複製代碼
這個和 Arrays.asList
同樣簡潔清晰。