在 Java 中初始化 List 的五種方法

yzbyzz發表於2019-03-04

在 Java 中初始化 List 的五種方法

Java 中經常需要使用到 List,下面簡單介紹幾種常見的初始化方式。

1.構造 List 後使用 List.add 初始化

List<String> stringList = new LinkedList<>();
stringList.add("a");
stringList.add("b");
stringList.add("c");
複製程式碼

這是最常規的做法,用起來不太方便。

2.使用 {{}} 雙括號語法

List<String> stringList = new LinkedList<String>(){{
    add("a");
    add("b");
    add("c");
}};
複製程式碼

這種方式相對方便了一些。

外層的 {} 定義了一個 LinkedList 的匿名內部類。內層的 {} 的定義了一個例項初始化程式碼塊。 這個程式碼塊在初始化內部類時執行。所以這裡相當於定義了一個匿名內部類,並使用 add 新增元素來初始化。

這種方式有幾個缺點:

  • 使用匿名內部類,會有效率上的損失。當然在大多數情況下,這點效率都是可接受的。
  • 靜態內部類持有所在外部類的引用。如果需要將 List 返回給到其他地方使用,可能造成記憶體洩漏。

3.使用 Arrays.asList

List<String> stringList = Arrays.asList("a", "b", "c");
複製程式碼

這種方式使用了 java.util.Arrays 的靜態方法。寫法上比之前的兩種都更簡潔,也沒有構造匿名內部類的效率問題。

但也有幾點需要注意:

  • 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++ 缺點的語言留下的一些影子。

雖然本文是在講初始化 List,但這裡的 {{}} 雙括號語法同樣可用於初始化 Map 等其他眾多型別。相對而言,Arrays.asList 就只能用於初始化 List 型別了。

4. 使用 Stream (JDK8)

List<String> list = Stream.of("a", "b", "c").collect(Collectors.toList());
複製程式碼

使用了 JDK8 的 Stream 來初始化。 單純初始化 List,使用 Stream 有點大材小用了。

5. 使用 Lists (JDK9)

List<String> list = Lists.newArrayList("a", "b", "c");
複製程式碼

這個和 Arrays.asList 一樣簡潔清晰。

參考

Double Brace Initialization

How to initialize List object in Java?

相關文章