在 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 上獲取。