在 Java 中為不可變列表新增一個元素
1. 概述
在 Java 中,不可變物件可確保執行緒安全並防止意外修改,從而形成健壯且可靠的程式碼。然而,有時,我們想將元素添加到不可變列表中。
在本快速教程中,我們將探討如何在 Java 中實現這一目標。
2.問題介紹
不可變列表不允許我們向其中添加元素。但在某些情況下,我們希望將其他元素合併到不可變清單中,而不影響其不變性。換句話說,我們想要一個包含給定不可變列表中的所有元素和新元素的不可變列表。
接下來,讓我們建立一個方法來執行此操作。為簡單起見,我們將使用單元測試斷言來驗證我們的解決方案是否產生預期結果。
3. 利用可變列表
解決該問題的一個想法是利用可變列表,例如ArrayList.
接下來,我們來詳細說明這個想法:
- 建立一個
ArrayList
來保存原始不可變清單中的所有元素 - 將新元素新增至
ArrayList
- 使
ArrayList
不可變
現在,讓我們在方法中實作邏輯:
static <T> List<T> appendAnElement(List<T> immutableList, T element) {
List<T> tmpList = new ArrayList<>(immutableList);
tmpList.add(element);
return Collections.unmodifiableList(tmpList);
}
如程式碼所示, appendAnElement()
是一個通用方法。它首先創建帶有給定immutableList
元素的ArrayList tmpList
。然後,它將element
新增到tmpList.
最後, Collections.unmodifiableList(tmpList)
作為結果傳回。顧名思義, Collections.unmodifiableList()
傳回指定清單的不可修改檢視。
接下來我們來測試一下方法。由於AssertJ 可以快速檢查集合是否是不可變的,因此我們將使用此庫來驗證我們的appendAnElement()
方法是否按預期工作:
List<String> myList = List.of("A", "B", "C", "D", "E");
List<String> expected = List.of("A", "B", "C", "D", "E", "F");
List<String> result = appendAnElement(myList, "F");
assertThat(result).isEqualTo(expected)
.isUnmodifiable();
由於**List.of()
方法傳回一個不可變的列表**,因此我們使用此方法來建立輸入myList
。
如果我們運行一下,測試就會通過。這樣,問題就解決了。然而,該方法只能為列表添加一個元素。
接下來,讓我們稍微擴展該方法以支援多個元素添加。
4. 新增多個元素
Varargs
(可變長度參數)允許方法接受任意數量的相同類型的參數。因此,我們可以使用這種技術來使我們的方法支援多個元素添加:
@SafeVarargs
static <T> List<T> appendElements(List<T> immutableList, T... elements) {
List<T> tmpList = new ArrayList<>(immutableList);
tmpList.addAll(Arrays.asList(elements));
return Collections.unmodifiableList(tmpList);
}
正如我們在上面的程式碼中看到的,我們將該方法註釋為@SafeVarargs
以確保我們的參數化Varargs
類型是安全的,並且不會導致堆污染。
使用這種方法,我們可以方便地將一個或多個元素添加到不可變列表中:
List<String> myList = List.of("A", "B", "C", "D", "E");
List<String> expected1 = List.of("A", "B", "C", "D", "E", "F");
List<String> result1 = appendElements(myList, "F");
assertThat(result1).isEqualTo(expected1)
.isUnmodifiable();
List<String> expected2 = List.of("A", "B", "C", "D", "E", "F", "G", "H", "I");
List<String> result2 = appendElements(myList, "F", "G", "H", "I");
assertThat(result2).isEqualTo(expected2)
.isUnmodifiable();
5. 結論
在本文中,我們探討如何在 Java 中為不可變列表新增元素,並示範如何使用Varargs
使方法接受可變數量的相同類型的參數。
與往常一樣,範例的完整原始程式碼可在 GitHub 上取得。