Java實現(xiàn)數(shù)組的復(fù)制及深淺拷貝的常見方法總結(jié)
在 Java 中,數(shù)組的復(fù)制涉及深淺拷貝問題。以下是幾種常用的方法:
1.淺拷貝(Shallow Copy)
只復(fù)制數(shù)組的引用,不復(fù)制數(shù)組元素本身。
方法一:使用=賦值(只是引用復(fù)制)
int[] original = {1, 2, 3, 4, 5};
int[] shallowCopy = original; // 只是引用復(fù)制
original[0] = 100;
System.out.println(shallowCopy[0]); // 輸出 100,兩個數(shù)組指向同一對象
方法二:clone()方法(數(shù)組淺拷貝)
// 對于基本類型數(shù)組,clone() 是深拷貝
int[] original = {1, 2, 3, 4, 5};
int[] copy = original.clone();
original[0] = 100;
System.out.println(copy[0]); // 輸出 1,因為是基本類型數(shù)組
// 對于對象數(shù)組,clone() 是淺拷貝
Person[] persons = {new Person("Alice"), new Person("Bob")};
Person[] shallowCopy = persons.clone();
persons[0].setName("Charlie");
System.out.println(shallowCopy[0].getName()); // 輸出 "Charlie"
方法三:Arrays.copyOf()
int[] original = {1, 2, 3, 4, 5};
int[] copy = Arrays.copyOf(original, original.length);
// 對于對象數(shù)組
Person[] persons = {new Person("Alice"), new Person("Bob")};
Person[] shallowCopy = Arrays.copyOf(persons, persons.length);
方法四:System.arraycopy()
int[] original = {1, 2, 3, 4, 5};
int[] copy = new int[original.length];
System.arraycopy(original, 0, copy, 0, original.length);
2.深拷貝(Deep Copy)
復(fù)制數(shù)組及其所有元素(包括嵌套對象)。
方法一:手動復(fù)制(推薦)
// 對于對象數(shù)組
class Person implements Cloneable {
private String name;
public Person(String name) { this.name = name; }
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 假設(shè) Person 是淺拷貝可接受的
// 或者返回 new Person(this.name); // 深拷貝
}
}
// 深拷貝實現(xiàn)
Person[] original = {new Person("Alice"), new Person("Bob")};
Person[] deepCopy = new Person[original.length];
for (int i = 0; i < original.length; i++) {
// 假設(shè) Person 類有合適的拷貝構(gòu)造方法
deepCopy[i] = new Person(original[i].getName());
// 或者使用 clone()
// deepCopy[i] = (Person) original[i].clone();
}
方法二:使用序列化(完全深拷貝)
import java.io.*;
public class DeepCopyUtil {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T deepCopy(T obj) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (T) ois.readObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
// 使用
Person[] persons = {new Person("Alice"), new Person("Bob")};
Person[] deepCopy = deepCopy(persons);
方法三:使用庫工具(如 Apache Commons Lang)
// 添加依賴:org.apache.commons:commons-lang3
import org.apache.commons.lang3.SerializationUtils;
// 對象必須實現(xiàn) Serializable
Person[] persons = {new Person("Alice"), new Person("Bob")};
Person[] deepCopy = SerializationUtils.clone(persons);
3.多維數(shù)組的深拷貝
// 二維數(shù)組深拷貝
int[][] original = {{1, 2}, {3, 4}};
int[][] deepCopy = new int[original.length][];
for (int i = 0; i < original.length; i++) {
deepCopy[i] = original[i].clone(); // 對于基本類型數(shù)組有效
}
// 對象二維數(shù)組
Person[][] persons = {{new Person("Alice")}, {new Person("Bob")}};
Person[][] deepCopy = new Person[persons.length][];
for (int i = 0; i < persons.length; i++) {
deepCopy[i] = new Person[persons[i].length];
for (int j = 0; j < persons[i].length; j++) {
deepCopy[i][j] = new Person(persons[i][j].getName());
}
}
4.Java 8+ 的流式操作
import java.util.Arrays;
// 對象數(shù)組深拷貝(需要合適的構(gòu)造方法)
Person[] original = {new Person("Alice"), new Person("Bob")};
Person[] deepCopy = Arrays.stream(original)
.map(p -> new Person(p.getName()))
.toArray(Person[]::new);
總結(jié)
| 方法 | 類型 | 特點 | 適用場景 |
|---|---|---|---|
| = 賦值 | 引用復(fù)制 | 最快,但共享同一對象 | 不需要獨立副本時 |
| clone() | 淺拷貝/深拷貝 | 基本類型數(shù)組是深拷貝 | 基本類型數(shù)組復(fù)制 |
| Arrays.copyOf() | 淺拷貝 | 簡潔易用 | 對象數(shù)組淺拷貝 |
| System.arraycopy() | 淺拷貝 | 高效,底層實現(xiàn) | 性能要求高的場景 |
| 手動循環(huán) | 可深可淺 | 最靈活 | 需要完全控制拷貝過程 |
| 序列化 | 深拷貝 | 完全獨立,但性能差 | 需要完全深拷貝,對象圖復(fù)雜 |
| Java 8 Stream | 可深可淺 | 函數(shù)式風(fēng)格 | 現(xiàn)代 Java 代碼 |
選擇建議:
- 基本類型數(shù)組:使用
clone()、Arrays.copyOf()或System.arraycopy() - 對象數(shù)組淺拷貝:使用
Arrays.copyOf()或System.arraycopy() - 對象數(shù)組深拷貝:手動實現(xiàn)或使用序列化
- 復(fù)雜對象圖:考慮使用序列化或第三方庫(如 Apache Commons Lang)
到此這篇關(guān)于Java實現(xiàn)數(shù)組的復(fù)制及深淺拷貝的常見方法總結(jié)的文章就介紹到這了,更多相關(guān)Java數(shù)組復(fù)制與拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot如何實現(xiàn)讀取.config文件
文章介紹如何在Java中讀取XML文件:通過創(chuàng)建XML數(shù)據(jù)源、定義POJO類(含父類Menudata和子類Menudatas)、編寫解析工具、實現(xiàn)Service層及Controller調(diào)用,最終使用Layui框架展示數(shù)據(jù),強調(diào)文件后綴轉(zhuǎn)換及層級結(jié)構(gòu)處理2025-08-08
SpringBoot中MybatisX插件的簡單使用教程(圖文)
MybatisX 是一款基于 IDEA 的快速開發(fā)插件,方便在使用mybatis以及mybatis-plus開始時簡化繁瑣的重復(fù)操作,本文主要介紹了SpringBoot中MybatisX插件的簡單使用教程,感興趣的可以了解一下2023-06-06
使用Mybatis-plus實現(xiàn)對數(shù)據(jù)庫表的內(nèi)部字段進行比較
這篇文章主要介紹了使用Mybatis-plus實現(xiàn)對數(shù)據(jù)庫表的內(nèi)部字段進行比較方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
10k+點贊的 SpringBoot 后臺管理系統(tǒng)教程詳解
這篇文章主要介紹了10k+點贊的 SpringBoot 后臺管理系統(tǒng)教程詳解,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01
如何解決websocket開啟多個頁面訪問同一個連接會失效的問題
使用WebSocket時,若多個頁面訪問同一個WebSocket連接可能會導(dǎo)致連接失效,遇到這個問題時,可以通過在SpringBoot中使用@ServerEndpoint注解并添加@Component來解決,出現(xiàn)連接錯誤通常是因為WebSocket連接接收到的是一個GET請求2024-09-09
NoHttpResponseException問題排查解決記錄分析
這篇文章主要為大家介紹了NoHttpResponseException問題排查解決記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08

