關(guān)于集合與數(shù)組轉(zhuǎn)換實(shí)現(xiàn)方法
在 Java 中,list.toArray()和Arrays.asList()是兩個(gè)常見的集合與數(shù)組轉(zhuǎn)換方法。
它們的行為和對原始數(shù)據(jù)的影響有顯著區(qū)別,下面詳細(xì)分析它們的機(jī)制及對數(shù)據(jù)修改的影響。如下圖示:

1、Arrays.asList()
1.1、方法作用
Arrays.asList(T....elements)將數(shù)組或多個(gè)元素轉(zhuǎn)換為一個(gè)List,返回的是java.util.Arrays.ArrayList(不是java.util.ArrayList)的實(shí)例。
1.2、內(nèi)部實(shí)現(xiàn)
- 這個(gè)List是基于原始數(shù)組的視圖,即底層直接引用原始數(shù)組。
- 該List的大小是固定的(不能添加或刪除元素),但可以修改元素內(nèi)容。
1.3、修改元素的影響
- 修改List中的元素→ 會(huì)影響原始數(shù)組,因?yàn)閮烧吖蚕硗粌?nèi)存地址。
- 修改原始數(shù)組的元素→ 也會(huì)影響List。
示例代碼
String[] arr = {"A", "B", "C"};
List<String> list = Arrays.asList(arr);
// 修改 List 中的元素
list.set(0, "X");
System.out.println(Arrays.toString(arr)); // 輸出: [X, B, C]
// 修改原始數(shù)組
arr[1] = "Y";
System.out.println(list); // 輸出: [X, Y, C]
1.4、注意事項(xiàng)
- 不能添加/刪除元素:調(diào)用add
()或remove()會(huì)拋出UnsupportedOperationException。 - 結(jié)構(gòu)修改限制:僅支持修改元素內(nèi)容,不支持改變集合大小。
2、list.toArray()
2.1、方法作用
list<T>.toArray()將集合轉(zhuǎn)換為一個(gè)數(shù)組,返回的是新數(shù)組的引用。
2.2、內(nèi)部實(shí)現(xiàn)
- 不論調(diào)用list.toArray()還是list.toArray()
(T[] a),最終都會(huì)創(chuàng)建一個(gè)新的數(shù)組,復(fù)制集合中的元素。 - 新數(shù)組與原始集合完全獨(dú)立,修改數(shù)組中的元素不會(huì)影響集合,反之亦然。
2.3、修改元素的影響
- 修改數(shù)組中的元素→ 不會(huì)影響原始集合。
- 修改集合中的元素→ 不會(huì)影響數(shù)組。
示例:
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
String[] arr = list.toArray(new String[0]);
// 修改數(shù)組中的元素
arr[0] = "X";
System.out.println(list); // 輸出: [A, B, C]
// 修改集合中的元素
list.set(1, "Y");
System.out.println(Arrays.toString(arr)); // 輸出: [X, B, C]
2.4、特殊情況
1、對象引用
如果集合中存儲(chǔ)的是對象引用(而非基本類型),修改對象的屬性會(huì)影響原始集合和數(shù)組,因?yàn)樗鼈冎赶蛲粋€(gè)對象實(shí)例。
示例:
List<User> list = new ArrayList<>();
User user = new User("Tom");
list.add(user);
User[] arr = list.toArray(new User[0]);
// 修改對象屬性
arr[0].setName("Jerry");
System.out.println(list.get(0).getName()); // 輸出: Jerry
2、數(shù)組copy
??注意:強(qiáng)行使用array增加元素copy。
可參考:
String[] array = {"1", "2"}; // 原始數(shù)組
String[] newArray = new String[array.length + 1]; // 新建長度+1的數(shù)組
System.arraycopy(array, 0, newArray, 0, array.length); // 復(fù)制舊元素
newArray[newArray.length - 1] = "3"; // 添加新元素
小結(jié):

3、對比總結(jié)

4、常見誤區(qū)與解決方案
4.1 誤區(qū):Arrays.asList()可以創(chuàng)建動(dòng)態(tài)列表
- 錯(cuò)誤:Arrays.asList()返回的列表是固定大小的,不能添加或刪除元素。
- 解決方案:如果需要?jiǎng)討B(tài)列表,需顯式轉(zhuǎn)換為 new ArrayList<>(Arrays.asList(.....))。
4.4 誤區(qū) :Arrays.asList()返回的是java.util.ArrayList
- 錯(cuò)誤:Arrays.asList()返回的是java.util.Arrays.ArrayList,不是java.util.ArrayList。
- 解決方案:如果需要?jiǎng)討B(tài)列表,顯式使用 new ArrayList<>()。
4.2 誤區(qū):list.toArray()返回的數(shù)組是集合的引用
- 錯(cuò)誤:list.toArray()返回的是新數(shù)組,與集合無直接關(guān)聯(lián)。
- 解決方案:如果需要共享數(shù)據(jù),應(yīng)直接操作集合或使用Arrays.asList()。
4.3 誤區(qū):對象引用的修改不會(huì)影響彼此
- 注意:如果數(shù)組或集合中的元素是對象引用,修改對象的屬性會(huì)同步到彼此。
- 解決方案:如果需要獨(dú)立拷貝,需手動(dòng)深拷貝對象。
5、實(shí)際應(yīng)用建議
- 需要修改元素且避免副作用:使用Arrays.asList(),但需確保不進(jìn)行結(jié)構(gòu)性修改。
- 需要獨(dú)立數(shù)組:使用list.toArray()。
- 需要?jiǎng)討B(tài)列表:使用 new ArrayList<>(Arrays.asList(.....))。
- 涉及對象引用時(shí):注意深拷貝或使用不可變對象。
舉例:
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
arrayList.add("4");
arrayList.add("5");
System.out.println("修改前的arrayList" + arrayList); // 輸出: [1, 2, 3, 4, 5]
System.out.println("arrayList的size==" + arrayList.size()); // 輸出: 5
// 轉(zhuǎn)換為數(shù)組
String[] array = arrayList.toArray(new String[0]);
array[0] = "6";
System.out.println("修改后的array" + Arrays.toString(array)); // 輸出: [6, 2, 3, 4, 5]
System.out.println("修改后的arrayList" + arrayList); // 輸出: [1, 2, 3, 4, 5]
關(guān)鍵點(diǎn)解釋
1.list.toArray()返回的是新數(shù)組
- arrayList.toArray(new String[0])會(huì)創(chuàng)建一個(gè)新的數(shù)組,并將arrayList中的所有元素復(fù)制到這個(gè)數(shù)組中。
- 新數(shù)組和arrayList是獨(dú)立的,它們的內(nèi)存地址不同。
2. 修改數(shù)組元素不影響原集合
- 在代碼中,array
[0] = "6"只是修改了數(shù)組的第 0 個(gè)元素,但arrayList仍然指向原來的字符串對象"1"。 - 因?yàn)镾tring是不可變類型(Immutable),所以修改數(shù)組中的元素不會(huì)影響arrayList中的值。
3. 為什么原集合沒有變化?
arrayList和array是兩個(gè)獨(dú)立的數(shù)據(jù)結(jié)構(gòu):
- arrayList是一個(gè)動(dòng)態(tài)集合,內(nèi)部通過數(shù)組實(shí)現(xiàn)。
- array是一個(gè)靜態(tài)數(shù)組,與arrayList無關(guān)。
修改array中的元素,不會(huì)改變arrayList內(nèi)部的數(shù)組內(nèi)容。
對比:如果元素是可變對象
如果集合中存儲(chǔ)的是可變對象(如自定義類),修改數(shù)組中的對象屬性會(huì)影響原集合,因?yàn)樗鼈円玫氖峭粋€(gè)對象實(shí)例。
- 例如:
class User {
String name;
public User(String name) { this.name = name; }
public void setName(String name) { this.name = name; }
}
List<User> list = new ArrayList<>();
User user = new User("Tom");
list.add(user);
User[] array = list.toArray(new User[0]);
// 修改數(shù)組中的對象屬性
array[0].setName("Jerry");
System.out.println(list.get(0).name); // 輸出: Jerry
// ? 可以動(dòng)態(tài)添加元素
List<String> list = new ArrayList<>(Arrays.asList("1", "2"));
list.add("3"); // 成功添加
// ? 無法動(dòng)態(tài)添加元素
List<String> stringList = Arrays.asList("3", "4");
stringList.add("3"); // 拋出 UnsupportedOperationException
stringList.add("4"); // 拋出 UnsupportedOperationException
核心原因:Arrays.asList()返回的List是固定大小的
總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot自定義MessageConvert詳細(xì)講解
正在學(xué)習(xí)SpringBoot,在自定義MessageConverter時(shí)發(fā)現(xiàn):為同一個(gè)返回值類型配置多個(gè)MessageConverter時(shí),可能會(huì)發(fā)生響應(yīng)數(shù)據(jù)格式錯(cuò)誤,或406異常(客戶端無法接收相應(yīng)數(shù)據(jù))。在此記錄一下解決問題以及追蹤源碼的過程2023-01-01
SpringBoot 單元測試實(shí)戰(zhàn)(Mockito,MockBean)
這篇文章主要介紹了SpringBoot 單元測試實(shí)戰(zhàn)(Mockito,MockBean),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
SpringBoot 整合 Netty 多端口監(jiān)聽的操作方法
Netty提供異步的、基于事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架,用以快速開發(fā)高性能、高可靠性的網(wǎng)絡(luò) IO 程序,是目前最流行的 NIO 框架,這篇文章主要介紹了SpringBoot 整和 Netty 并監(jiān)聽多端口,需要的朋友可以參考下2023-10-10
MyBatis-Plus自動(dòng)填充功能失效導(dǎo)致的原因及解決
這篇文章主要介紹了MyBatis-Plus自動(dòng)填充功能失效導(dǎo)致的原因及解決,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
使用webservice自定義注解處理參數(shù)加解密問題
這篇文章主要介紹了使用webservice自定義注解處理參數(shù)加解密問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Java HttpClient-Restful工具各種請求高度封裝提煉及總結(jié)
這篇文章主要介紹了Java HttpClient-Restful工具各種請求高度封裝提煉及總結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10

