在 Java 中將字符串的 ArrayList 轉換為字符串數組
1. 概述
在 Java 中,數據操作通常涉及將數據結構從一種形式轉換為另一種形式。一項常見任務是將String的ArrayList轉換為String數組。
在本教程中,我們將探索如何使用 Java 的內置方法和技術無縫地完成這種轉換。
2.問題介紹
舉個例子可以幫助我們快速理解問題。假設我們有以下ArrayList,其中包含一些藝術家的名字:
static final List<String> INPUT_LIST = Lists.newArrayList("Michael Bolton", "Michael Jackson", "Guns and Roses", "Bryan Adams", "Air Supply");
現在,我們想要將此ArrayList轉換為String數組,其中按相同順序包含相同藝術家的姓名:
static final String[] EXPECTED_ARRAY = new String[] { "Michael Bolton", "Michael Jackson", "Guns and Roses", "Bryan Adams", "Air Supply" };
這看起來是一個簡單的任務,因為 Java 標準庫提供了Collection.toArray()方法將集合轉換為數組。 toArray()方法返回一個Object[]數組。由於列表的類型為List<String>,所有元素都是字符串。所以我們可能認為將對像數組轉換為String[]:
String[] result = (String[]) INPUT_LIST.toArray();
如果我們運行這行代碼,我們可以看到以下輸出:
java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.String;
正如我們所看到的,拋出了ClassCastException 。這是因為Java的泛型類型只在編譯時存在。也就是說,在運行時, toArray()方法返回的數組並不知道其元素的具體類型。它們可以是String 、 Integer ,甚至可以是不同類型的混合,因為Object類是所有其他類型的超類型。因此,Java 拋出ClassCastException並拒絕Object[]到String[]的轉換。
接下來,讓我們看看將字符串ArrayList轉換為字符串數組的正確方法。為簡單起見,我們將使用單元測試斷言來驗證每種方法是否返回預期結果。
3. 在循環中填充預先聲明的字符串數組
解決我們的問題的一個簡單的想法是遍歷字符串ArrayList ,獲取每個元素,並填充預先聲明的字符串數組。接下來我們來實現一下:
String[] result = new String[INPUT_LIST.size()];
for (int i = 0; i < INPUT_LIST.size(); i++) {
result[i] = INPUT_LIST.get(i);
}
assertArrayEquals(EXPECTED_ARRAY, result);
在上面的實現中,我們首先聲明了一個字符串數組,其長度與給定的ArrayList.然後,我們在for循環中填充數組。
4. 使用toArray(T[] a)方法
之前我們在使用Collection.toArray()方法時遇到了ClassCastException 。 Collection接口還定義了另一個帶有參數T[] a的toArray()方法:
<T> T[] toArray(T[] a);
方法簽名顯示該方法返回T[]而不是Object[] 。接下來我們看看如何使用:
String[] result = new String[INPUT_LIST.size()];
INPUT_LIST.toArray(result);
assertArrayEquals(EXPECTED_ARRAY, result);
如上面的代碼所示,我們創建了一個新的字符串數組,為列表元素提供了足夠的空間。因此,將其傳遞給toArray()後,數組將由列表中的元素填充。
但是,如果我們傳遞給toArray()的字符串數組沒有足夠的空間容納列表元素,我們將從toArray():
String[] result2 = INPUT_LIST.toArray(new String[0]);
assertArrayEquals(EXPECTED_ARRAY, result2);
5. 使用流API
假設我們使用 Java 8 或更高版本。我們還可以使用 Stream API 來解決這個問題:
String[] result = INPUT_LIST.stream()
.toArray(String[]::new);
assertArrayEquals(EXPECTED_ARRAY, result);
Stream的toArray()方法接受一個生成器函數,該函數以所需的類型分配返回的數組。在這種情況下,我們可以簡單地將String[]的構造函數作為方法引用,並將其作為函數傳遞給toArray() 。
6.Java 11+
最後,如果我們使用Java 11或更高版本,我們可以直接調用Collection.toArray(generatorFunc)來獲取轉換後的數組,而無需先將列表轉換為Stream :
String[] result = INPUT_LIST.toArray(String[]::new);
assertArrayEquals(EXPECTED_ARRAY, result);
七、結論
在本文中,我們首先討論了為什麼(String[])myList.toArray()會拋出ClassCastException.然後,我們通過示例學習了將String ArrayList轉換為String數組的不同方法。
與往常一樣,示例的完整源代碼可在 GitHub 上獲取。