將集合作為 Varargs 參數傳遞
1. 概述
在本教程中,我們將探索提供Collection
作為varargs
參數的參數的不同方法。
2.什麼是arargs
參數?
變數參數,簡稱varargs
,是在 Java 5 中引入的。
public void method(String... strings) {}
變數參數允許我們將任意數量的相同類型的變數傳遞給方法。例如,如果我們有三個String
變量,我們可以在呼叫我們的方法時直接傳遞它們:
method(s1, s2, s3);
在底層,一個陣列被實例化並根據傳遞的參數填充。
3. 理解問題
正如我們所示範的,當我們要傳遞不同的變數時,呼叫帶有varargs
參數的方法很容易。然而,我們可能會發現我們的變數包含在一個Collection
中。
假設我們有一個String
List
,我們探索將此Collection
傳遞給varargs
參數的不同方法:
List<String> listOfStrings = List.of(s1, s2, s3);
4. 使用傳統的for
迴圈來填入數組
我們可以使用傳統的for
迴圈來填入List.
然後我們可以直接將此數組傳遞給我們的方法:
@Test
void givenList_whenUsingForLoopToPopulateArray_thenInvokeVarargsMethod() {
String[] array = new String[listOfStrings.size()];
for (int i = 0; i < listOfStrings.size(); i++) {
array[i] = listOfStrings.get(i);
}
assertDoesNotThrow(() -> method(array));
}
正如我們在上面看到的,我們迭代List
中的元素並使用索引將它們放入新數組中。值得注意的是,我們無法將這種方法用於無序Collection
(例如Set
。因此,下一種方法為我們提供了更大的靈活性。
5. 使用Collection.toArray()
方法
Collection
的每個子類型都必須實作toArray()
方法。透過使用toArray(T[] a)
重載,我們可以直接取得一個陣列並將該陣列傳遞給varargs
方法參數:
@Test
void givenList_whenUsingCollectionToArray_thenInvokeVarargsMethod() {
assertDoesNotThrow(() -> method(listOfStrings.toArray(new String[0])));
}
在這裡,我們也可以使用default toArray(IntFunction<A[]> generator)
方法:
method(listOfStrings.toArray(String[]::new));
此方法還允許我們透過建構函數引用提供要從Collection
元素填充的陣列。因此,無論哪種方式,我們都可以獲得所需類型的數組,而無需進行任何轉換。如果我們使用僅傳回Object
數組的toArray()
方法,情況就不會如此。
6. 使用Stream.toArray()
方法
另一種方法是利用Stream
類別的toArray(IntFunction<A[]> generator)
方法從List
中取得陣列:
@Test
void givenList_whenUsingStreamAPI_thenInvokeVarargsMethod() {
String[] array = listOfStrings.stream().toArray(String[]::new);
assertDoesNotThrow(() -> method(array));
}
正如我們所看到的,我們從List
中取得一個流,並呼叫終端機操作toArray()
將元素收集到一個陣列中。此外,我們還需要在此處提供函數來實例化所需的陣列。
如果我們需要在元素上合併過濾或轉換邏輯,函數式程式設計會非常強大。因此,我們可以透過使用中間的map()
和filter()
操作來輕鬆實現這一點。
七、結論
在本文中,我們探討了varargs
參數是什麼以及它的幕後工作原理。因此,這使我們能夠探索將Collection
傳遞給varargs
參數的不同方法。此外,我們透過探索 Stream API 簡要介紹了 Java 中的函數式程式設計。
與往常一樣,本文中使用的程式碼範例可在 GitHub 上取得。