Arrays.asList() 與 Collections.singletonList()
一、概述
List
是我們使用 Java 時常用的集合類型。
眾所周知,我們可以很容易地在一行中初始化一個List
。例如,當我們想要初始化一個只有一個元素的List
時,我們可以使用Arrays.asList()
方法或Collections.singletonList()
方法。
在本教程中,我們將討論這兩種方法之間的區別。然後,為簡單起見,我們將使用單元測試斷言來驗證某些操作是否按預期運行。
2. Arrays.asList()
方法
首先, Arrays.asList()
方法返回一個固定大小的列表。
任何結構更改都會拋出UnsupportedOperationException
,例如,向列表中添加新元素或從列表中刪除元素。現在,讓我們通過測試來檢查一下:
List<String> arraysAsList = Arrays.asList("ONE");
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
() -> arraysAsList.add("TWO")
);
如果我們試一試,測試就通過了。在上面的代碼中,我們使用 Assertj 的異常斷言來驗證當我們嘗試向列表中添加新元素時是否拋出UnsupportedOperationException
。
即使我們不能在列表上調用add()
或remove()
操作,我們也可以使用set()
方法更改列表中的元素:
arraysAsList.set(0, "A brand new string");
assertThat(arraysAsList.get(0)).isEqualTo("A brand new string");
這一次,我們用一個新的String
對象設置列表中的元素。如果我們執行測試,它就會通過。
最後我們來討論一下Arrays.asList()
方法的數組和返回的列表的關係。
正如方法名稱所暗示的,此方法使數組作為List
工作。讓我們了解“使數組作為List
工作”的含義。
Arrays.asList()
方法返回一個由給定數組支持的List
對象。也就是說,該方法不會將數組中的元素複製到新的List
對像中。相反,該方法提供給定數組的List
視圖。因此,我們對數組所做的任何更改都將在返回的列表中可見。同樣,對列表所做的更改也將在數組中可見:
String[] theArray = new String[] { "ONE", "TWO" };
List<String> theList = Arrays.asList(theArray);
//changing the list, the array is changed too
theList.set(0, "ONE [changed in list]");
assertThat(theArray[0]).isEqualTo("ONE [changed in list]");
//changing the array, the list is changed too
theArray[1] = "TWO [changed in array]";
assertThat(theList.get(1)).isEqualTo("TWO [changed in array]");
測試通過。因此,對於數組和返回的列表,如果我們在一側進行了一些更改,那麼另一側也會發生更改。
3. Collections.singletonList()
方法
首先, singletonList()
方法返回的列表只有一個元素。與Arrays.asList()
方法不同, singletonList()
返回一個不可變列表。
換句話說,不允許對singletonList().
一個測試可以快速說明這一點:
List<String> singletonList = Collections.singletonList("ONE");
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
() -> singletonList.add("TWO")
);
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
() -> singletonList.set(0, "A brand new string")
);
如果我們運行測試,它就會通過。因此,無論我們是向列表中添加元素還是更改列表中的元素,它都會拋出UnsupportedOperationException.
值得一提的是,如果我們看一下返回列表類的源代碼,與其他List
實現不同,返回列表中的單個元素不存儲在數組或任何其他復雜的數據結構中。相反,列表直接保存元素對象:
private static class SingletonList<E> extends AbstractList<E> implements RandomAccess, Serializable {
...
private final E element;
SingletonList(E obj) {element = obj;}
...
}
因此,它將佔用更少的內存。
4. 簡短總結
最後,讓我們將Arrays.asList()
方法和Collections.singletonList()
方法的特點總結在一個表格中,以便更好地概覽:
Arrays.asList() |
Collections.singletonList() |
|
---|---|---|
結構變化 | 不允許 | 不允許 |
非結構性變化 | 允許 | 不允許 |
數據結構 | 由陣列支持 | 直接握住元素 |
5. 結論
在這篇快速文章中,我們討論了Arrays.asList()
方法和Collections.singletonList()
方法。
當我們想初始化一個只有一個元素的固定大小的列表時,我們可以考慮使用Collections.singletonList()
方法。但是,如果需要更改返回列表中的元素,我們可以選擇Arrays.asList()
方法。
與往常一樣,示例的完整源代碼可在 GitHub 上獲得。