Java實(shí)現(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,兩個(gè)數(shù)組指向同一對(duì)象
方法二:clone()方法(數(shù)組淺拷貝)
// 對(duì)于基本類型數(shù)組,clone() 是深拷貝
int[] original = {1, 2, 3, 4, 5};
int[] copy = original.clone();
original[0] = 100;
System.out.println(copy[0]); // 輸出 1,因?yàn)槭腔绢愋蛿?shù)組
// 對(duì)于對(duì)象數(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);
// 對(duì)于對(duì)象數(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ù)組及其所有元素(包括嵌套對(duì)象)。
方法一:手動(dòng)復(fù)制(推薦)
// 對(duì)于對(duì)象數(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); // 深拷貝
}
}
// 深拷貝實(shí)現(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;
// 對(duì)象必須實(shí)現(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(); // 對(duì)于基本類型數(shù)組有效
}
// 對(duì)象二維數(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;
// 對(duì)象數(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é)
| 方法 | 類型 | 特點(diǎn) | 適用場景 |
|---|---|---|---|
| = 賦值 | 引用復(fù)制 | 最快,但共享同一對(duì)象 | 不需要獨(dú)立副本時(shí) |
| clone() | 淺拷貝/深拷貝 | 基本類型數(shù)組是深拷貝 | 基本類型數(shù)組復(fù)制 |
| Arrays.copyOf() | 淺拷貝 | 簡潔易用 | 對(duì)象數(shù)組淺拷貝 |
| System.arraycopy() | 淺拷貝 | 高效,底層實(shí)現(xiàn) | 性能要求高的場景 |
| 手動(dòng)循環(huán) | 可深可淺 | 最靈活 | 需要完全控制拷貝過程 |
| 序列化 | 深拷貝 | 完全獨(dú)立,但性能差 | 需要完全深拷貝,對(duì)象圖復(fù)雜 |
| Java 8 Stream | 可深可淺 | 函數(shù)式風(fēng)格 | 現(xiàn)代 Java 代碼 |
選擇建議:
- 基本類型數(shù)組:使用
clone()、Arrays.copyOf()或System.arraycopy() - 對(duì)象數(shù)組淺拷貝:使用
Arrays.copyOf()或System.arraycopy() - 對(duì)象數(shù)組深拷貝:手動(dòng)實(shí)現(xiàn)或使用序列化
- 復(fù)雜對(duì)象圖:考慮使用序列化或第三方庫(如 Apache Commons Lang)
到此這篇關(guān)于Java實(shí)現(xiàn)數(shù)組的復(fù)制及深淺拷貝的常見方法總結(jié)的文章就介紹到這了,更多相關(guān)Java數(shù)組復(fù)制與拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Jedis NOAUTH Authentication required問題解決方法
這篇文章主要介紹了Java Jedis NOAUTH Authentication required問題解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07
Java解決浮點(diǎn)數(shù)計(jì)算不精確問題的方法詳解
在 Java 中,浮點(diǎn)數(shù)計(jì)算不精確問題指的是使用浮點(diǎn)數(shù)進(jìn)行運(yùn)算時(shí),由于浮點(diǎn)數(shù)的內(nèi)部表示方式和十進(jìn)制數(shù)的表示方式存在差異,導(dǎo)致計(jì)算結(jié)果可能出現(xiàn)誤差,本文就給大家介紹一下Java如何解決浮點(diǎn)數(shù)計(jì)算不精確問題,需要的朋友可以參考下2023-09-09
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(30)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你2021-07-07
Spring的@PreAuthorize注解自定義權(quán)限校驗(yàn)詳解
這篇文章主要介紹了Spring的@PreAuthorize注解自定義權(quán)限校驗(yàn)詳解,由于項(xiàng)目中,需要對(duì)外開放接口,要求做請(qǐng)求頭校驗(yàn),不做其他權(quán)限控制,所以準(zhǔn)備對(duì)開放的接口全部放行,不做登錄校驗(yàn),需要的朋友可以參考下2023-11-11
springboot2中使用@JsonFormat注解不生效的解決
這篇文章主要介紹了springboot2中使用@JsonFormat注解不生效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Java判斷是否為簡體中文字符的實(shí)現(xiàn)方法
在應(yīng)用開發(fā)中,判斷簡體中文字符是一個(gè)重要但常被忽視的任務(wù),簡體中文和繁體中文在字符上有顯著的區(qū)別,因此在某些場景下我們需要判斷輸入的文本是否為簡體中文,本文將介紹如何使用Java進(jìn)行此判斷,并提供相應(yīng)的代碼示例,幫助開發(fā)者更好地理解這一過程2024-09-09
SpringCloud?Stream?快速入門實(shí)例教程
本文介紹了Spring?Cloud?Stream(SCS)組件在分布式系統(tǒng)中的作用,以及如何集成到Spring?Boot項(xiàng)目中,通過SCS,可以統(tǒng)一管理不同的消息隊(duì)列中間件,并提供了更高級(jí)的抽象,感興趣的朋友跟隨小編一起看看吧2025-11-11
Java編譯錯(cuò)誤java.lang.NoSuchFieldError的解決方案詳析
java.lang.NoSuchFieldError是 Java 中的一種運(yùn)行時(shí)錯(cuò)誤,這篇文章主要介紹了Java編譯錯(cuò)誤java.lang.NoSuchFieldError的解決方案,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-11-11

