Java复制数组的五种方式

java数组拷贝的方法 该方法会返回一个新的数组对象,且改变新数组中的元素值,不会影响原来的数组。因为第一种数组拷贝方式,我们已经在数组扩容的案例中给大家演示了,这里就不再重复展示相关代码了。小千在给大家讲解数组扩容时,涉及到了数组中数据元素的拷贝复制。System.arraycopy()是Java提供的一个本地静态方法,用于将数据元素从源数组复制到目标数组。1. 通过循环语句,将原数组中的各个元素拷贝到新数组中(即数组扩容案例中使用的方法);: 表示新数组的长度。如果新数组的长度超过源数组的长度,会采用数组元素类型的默认值。 阅读详情

参考:https://blog.youkuaiyun.com/u011669700/article/details/79323251 

Java中数组复制的几种方式以及数组合并

1.Object.clone()

   简单直接,只能对源数组完整地复制

2.Arrays.copyOf(T[] original, int newLength)

   可以只复制源数组中部分元素,但复制的起始位置固定为0

3.Arrays.copyOfRange(T[] original, int from, int to)

   可以指定复制的起始位置

4.System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

   复杂,但可以将源数组中的部分元素复制到目标数组的指定位置(此方法最灵活,可实现上述1、2、3的功能)

5.for循环

代码灵活,但效率低

1、clone 方法

clone方法是从Object类继承过来的,基本数据类型(String ,boolean,char,byte,short,float ,double,long)都可以直接使用clone方法进行克隆,注意String类型是因为其值不可变所以才可以使用。

int 类型示例

int[] a1 = {1, 3};
int[] a2 = a1.clone();

a1[0] = 666;
System.out.println(Arrays.toString(a1));   //[666, 3]
System.out.println(Arrays.toString(a2));   //[1, 3]



String类型示例

String[] a1 = {"a1", "a2"};
String[] a2 = a1.clone();

a1[0] = "b1"; //更改a1数组中元素的值
System.out.println(Arrays.toString(a1));   //[b1, a2]
System.out.println(Arrays.toString(a2));   //[a1, a2]

2、System.arraycopy

System.arraycopy方法是一个本地的方法,源码里定义如下:public static native void arraycopy(Object src, int srcPos, Object dest, int desPos, int length);

其参数含义为:(原数组, 原数组的开始位置, 目标数组, 目标数组的开始位置, 拷贝个数)

用法示例

int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = new int[10];

System.arraycopy(a1, 1, a2, 3, 3);
System.out.println(Arrays.toString(a1)); // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(a2)); // [0, 0, 0, 2, 3, 4, 0, 0, 0, 0]

当使用这个方法的时候,需要复制到一个已经分配内存单元的数组。

3、 Arrays.copyOf

Arrays.copyOf底层其实也是用的System.arraycopy 源码如下:

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
    @SuppressWarnings("unchecked")
    T[] copy = ((Object)newType == (Object)Object[].class)
        ? (T[]) new Object[newLength]
        : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy;
}

参数含义:(原数组,拷贝的个数)
用法示例:

int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = Arrays.copyOf(a1, 3);

System.out.println(Arrays.toString(a1)) // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(a2)) // [1, 2, 3]

使用该方法无需我们事先使用new关键字对对象进行内存单元的分配

4、 Arrays.copyOfRange

Arrays.copyOfRange底层其实也是用的System.arraycopy,只不过封装了一个方法

public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) {
    int newLength = to - from;
    if (newLength < 0)
        throw new IllegalArgumentException(from + " > " + to);
    @SuppressWarnings("unchecked")
    T[] copy = ((Object)newType == (Object)Object[].class)
        ? (T[]) new Object[newLength]
        : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    System.arraycopy(original, from, copy, 0,
                     Math.min(original.length - from, newLength));
    return copy;
}

参数含义(原数组,开始位置,拷贝的个数)
用法示例:

int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = Arrays.copyOfRange(a1, 0, 1);

System.out.println(Arrays.toString(a1)) // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(a2)) // [1]

最后需要注意的是基本类型的拷贝是不影响原数组的值的,如果是引用类型,就不能在这用了,因为数组的拷贝是浅拷贝,对于基本类型可以,对于引用类型是不适合的。

5、那么如何实现对象的深度拷贝呢?

5.1 实现Cloneable接口
实现Cloneable接口,并重写clone方法,注意一个类不实现这个接口,直接使用clone方法是编译通不过的。

/**
 * Created by Joe on 2018/2/13.
 */
public class Dog implements Cloneable {
    private String id;
    private String name;

    public Dog(String id, String name) {
        this.id = id;
        this.name = name;
    }

    // 省略 getter 、 setter 以及 toString 方法

    @Override
    public Dog clone() throws CloneNotSupportedException {
        Dog dog = (Dog) super.clone();

        return dog;
    }
}

示例:

Dog dog1 = new Dog("1", "Dog1");
Dog dog2 = dog1.clone();

dog2.setName("Dog1 changed");

System.out.println(dog1); // Dog{id='1', name='Dog1'}
System.out.println(dog2); // Dog{id='1', name='Dog1 changed'}

5.2 组合类深拷贝
如果一个类里面,又引用其他的类,其他的类又有引用别的类,那么想要深度拷贝必须所有的类及其引用的类都得实现Cloneable接口,重写clone方法,这样以来非常麻烦,简单的方法是让所有的对象实现序列化接口(Serializable),然后通过序列化反序列化的方法来深度拷贝对象。

public Dog myClone() {
    Dog dog = null;

    try {
        //将对象序列化成为流,因为写在流是对象里的一个拷贝
        //而原始对象扔在存在JVM中,所以利用这个特性可以实现深拷贝
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(this);

        //将流序列化为对象
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        dog = (Dog) objectInputStream.readObject();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }

    return dog;
}

总结:
本文介绍了关于Java里面的数组拷贝的几种方式和用法,并给出了如何在Java里面实现对象的深度拷贝,注意除非必需,一般情况下不要使用对象的深度拷贝,因为性能较差。除了自己实现深度拷贝的功能外,网上也有一些开源的工具类也集成了这些功能,如Apache Common Lang3,但原理都大同小异,感兴趣的同学可以自己去学习下。


 

Java中数组的5种拷贝方法 Java中数组的5种拷贝方法:1、for循环;2、调用Object类中的clone()方法;3、Arrays类中的Arrays.copyOf()方法;4、copyOfRange()方法;5、System.arraycopy()方法 阅读详情

相关推荐

Java数组篇[7]:数组拷贝

在Java程序设计中,经常需要复制数组或创建数组的克隆。这在修改数组内容时保留原始数据不变,或者在多线程环境中避免数据竞争时非常有用。本文将探讨Java中数组拷贝和克隆的不同方法,包括手动拷贝、使用方法、以及数组的克隆。数组拷贝是创建数组内容的一个副本,而克隆则是创建数组对象的一个完整副本。在Java中,数组是引用类型,所以简单的赋值操作只会复制引用,而不是数组对象本身。clone():数组的clone()方法返回数组的一个副本。数组的拷贝和克隆是Java编程中常见的操作。

喵手的博客 1570

【Java】第7章_Array_Enum 上机实践与习题

List实验1 遍历与复制数组实验2 公司与薪水习题7 实验1 遍历与复制数组 Arrays.copyOf(a, 4); //代码1 Arrays.toString(c); //代码2 Arrays.copyOfRange(a, a.length - 4, a.length); //代码3 c[c.length - 1] = -100; //代码4 实验2 公司与薪水 Employee[]...

博客皆笔记 1430

记录思科cisco交换机升级iso步骤

Cisco Nexus 93180交换机版本升级

a635161812的博客 4376

惊呆了!Java小白快速入门的实验居然在这里!建议收藏!!!【实验二】

实验要求: 一、【输出希腊字母表】编写一个Java应用程序,该程序在命令行窗口输出希腊字母表。 二、【数组的引用与元素】编写一个Java应用程序,该程序在命令行窗口输出数组的引用以及元素的值。 三、【遍历与复制数组】编写一个Java应用程序,输出数组a的全部元素;将数组a的全部或部分元素复制到数组b中;改变数组b的元素值并输出;输出数组a的全部元素。 一、【输出希腊字母表】 题目描述:编写一个Java应用程序,该程序在命令行窗口输出希腊字母表。 步骤: ①新建一个文本文档,在文本文档中写入代码

憨憨猿学编程 2757

2025 年第十五届 APMCM 亚太地区大学生数学建模竞赛A题 农业灌溉系统优化

该摘要探讨了农业灌溉系统优化面临的复杂挑战,涉及智能灌溉技术的应用与资源配置问题。研究聚焦于一个1公顷的方形农场案例,该农场种植三种作物并面临动态环境条件(土壤类型、气象变化)。系统优化需平衡河流引水(非线性成本函数:C=50L^1.2+0.1Q^1.5)与储水罐灌溉(成本5元/升容积)两种方案,同时满足喷灌技术约束(喷头间距≥15米,覆盖半径15米)。关键矛盾体现在"平河旱储"的水资源调配策略与多作物需水量差异之间的协调,需通过传感器数据实时调整灌溉方案以实现效率最大化。(149字)

m0_60472361的博客 641

CH340以及CH系列USB转串口驱动下载

在之前使用USB转串口时,很多时候大家可能会不知道去哪下载驱动,然后百度随便下载一个,但往往鱼龙混杂且版本不一,所以今天特意整理一下CH340驱动以及CH系列的官方驱动下载地址,方便大家进行下载也方便自己后期查找,所有链接皆指向官方下载链接,每次下载都可获取官方当前最新驱动。 CH340/CH341 Windows驱动下载链接:CH341SER.EXE下载链接 Linux驱动下载链接:CH341SER_LINUX.ZIP下载链接 Andr...

OIDCAT的博客 4万+

java-使用IO流复制文件主要的五种方法

IO流中对文件的操作有很多,现在总结在IO流中对文件复制的操作: 1.如果被复制文件是文本文件,则可以使用字符流操作,也可以使用字节流操作 2.如果被复制文件是非文本文件,只能通过字节流复制 现举例复制两个文本文档:使用专用于操作文本的字符流实现 方法一:一次复制一个字节 pu

smiletomyself的专栏 2821

MiniMaxH3+ComfyUI本地部署:一键整合包、工作流搭建与报错排查

本地部署视频生成模型时,模型权重、推理框架与自定义节点的匹配是核心挑战。MiniMaxH3作为多模态生成模型,通常依赖ComfyUI这类节点式工作流引擎实现可视化调度。一键整合包将Python环境、PyTorch算子、模型文件预置封装,大幅降低部署门槛,并通过半精度加载、显存碎片回收等机制优化推理速度。在文生视频、图生视频与批量生成场景中,清晰的节点链路和参数调优能力直接影响输出质量与显存占用。针对模型不识别、节点执行失败等高频问题,系统排查命令行日志与模型目录可快速定位故障。本文以MiniMaxH3整合包

weixin_29047545的博客 579

java数组复制

在 Java 中,复制数组的方法多种多样,选择适合的方法取决于具体需求,如性能、灵活性和易用性。对于大多数情况,推荐使用和方法。

qq_27390023的博客 354

永磁同步电机矢量控制——电流内环前馈解耦策略

在采用永磁同步电机矢量控制时,ud和uq的指令值存在耦合项。需要对其进行解耦,目前,常用的解耦设计方法有前馈解耦、偏差解耦以及内模控制,本文主要分享电流内环前馈解耦控制策略。

a12312341ll的博客 8691

安路TangDynasty和FD和JTAG驱动器安装

安路FPGA产品矩阵包含SALPHOENIX高性能、SALEAGLE高性价比和SALELF低功耗三大系列,广泛应用于网络通信、消费电子等领域。配套的TangDynasty(TD)集成开发环境支持标准设计输入,提供完整优化流程与调试工具。简要介绍了TD 6.2.1版本的安装步骤。

wangjie36的博客 1030

常用的五种复制数组的方法

c

tiandiwujix的博客 1346

C# & SQL Server 实时数据同步:7步轻松搞定,代码详解

实时数据同步是指在一个数据库中的数据发生变化时,能够立即或近乎立即地将这些变化同步到另一个数据库中。这种同步可以是单向的(从源数据库同步到目标数据库),也可以是双向的(两个数据库互相同步)。通过本文的详细讲解和代码示例,相信你已经学会了如何使用C#和SQL Server实现数据库的实时数据同步。实时数据同步不仅可以提升系统的响应速度,还能确保数据的一致性和准确性。希望这篇教程对你有所帮助,期待你在C#编程中取得更大的成就!🌟✨如果你有任何问题或建议,欢迎在评论区留言交流!

java专栏 514

使用输入输出IO流以及缓冲流实现文本文件复制的五种方法

IO流以及缓冲流可以帮我们实现文本文件的读写操作, 关于它们的使用可以去参考这篇博客io流/缓冲流. 接下来我们直接来看复制文本文件的五种方法,直接看代码: package com.qibao.iostream; import java.io.BufferedReader; import java.io.BufferedWriter; import...

168

【教程4>第7章>第6节】基于FPGA的Viterbi维特比译码verilog实现——ACS加比选单元1

本文介绍了ACS加比选单元模块在FPGA中的实现过程,重点讲解了维特比译码中的ACS单元功能及其在硬件实现中的关键问题。文章首先概述了ACS单元在维特比译码中的作用,即通过计算和比较分支度量值来选择最优路径。接着,详细描述了FPGA实现中的分支度量值归一化处理策略,并指出了其存在的弊端。随后,文章提供了基于Verilog的ACS加比选单元模块代码,解释了其输入输出端口及工作流程。最后,总结了本小节内容,并预告了下一章节将涉及ACS顶层模块的开发与仿真测试。

FPGA/MATLAB学习教程/源码/项目合作开发 568

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

java数组

1 数组本身就是一种数据类型,可以存放数据(基本数据类型和引用数据类型){什么数据类型都能放,但只能放同一种数据类型}3 Arrays.copyOf(数组名,n(n代表新数组的长度)) 要复制的数组,会得到一个新数组。二.int[] array1 = new int[]{1,2,3,4,5,6,7};三.int[] array2 = {1,2,3,4,5,6,7,8,9};2 Arrays.sort(数组名) 数组的排序,正序排练。数组的最大索引是数组的长度减一 数组名.length-1。

wpxhjl的博客 105

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Java学习——摸清数组及其应用

本文为大家带来Java数组中的知识及一些应用,希望对你有所帮助~~

weixin_53919192的博客 745

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

JAVA——实现 字符流的练习之5种方式复制文本文件

JAVA——实现 字符流的练习之5种方式复制文本文 代码如下: public class Demo7 { public static void main(String[] args) throws IOException { // 基本的字符流一次读写一个字符 method1(); // 基本的字符流一次读写一个字符数组 method2(); // 高效的字符流一...

东城庞太师 456

浅析各种编程语言对数组的不同用法(以java,python,C,C++,javaScript为例)

浅析各种编程语言对数组的不同用法 (以java,python,C,C++,javaScript为例) C语言 C语言作为比较基础的语言,很多东西都需要自己实现 例如遍历整个数组输出所有值 int main(){ int a[10]={1,2,3,4,5,6,7,8,9,10}; int i; for(i=0;i<10;i++){ printf("%d ...

PickCake的博客 773

IO流之复制文件的五种方式(读取一个字符,读取一个字符数组,缓冲流读取一个字符,读取一个字符数组,读取一行)

package IOliu.DemoCopyFive; import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper; import java.io.*; public class DemoTest { static String srcFileName="F:\\untitledxuexi\\src\\IO...

AFacetoj的博客 271

Day09 -- 【Java全栈】数组(下)

后面会详细讲,现在可以先了解个大概用static修饰的方法,属于类本身,不属于任何一个对象。直接用类名调用,不用创建对象用类名直接调,不用 new 对象。静态方法是公共设施,属于类本身,大家随时直接用。System.arraycopy(源数组, 源起始位置, 目标数组, 目标起始位置, 复制个数);// 参数:源数组, 源起始位置, 目标数组, 目标起始位置, 复制个数。

FTE326459的博客 611

java的字符流的应用_javaIO流中字符流的应用

public class FiveKindIO {public static void main(String[] args) throws Exception {//被复制的文件String src = "Regex.java";//复制到哪儿??String dest = "Regex02.java";//调用方法实现文件复制method4(src,dest);}//基本字符流一次读写一个字符...

weixin_31977649的博客 104

java里的字符流_javaIO流中字符流的应用

public classFiveKindIO {public static void main(String[] args) throwsException {//被复制的文件String src = "Regex.java";//复制到哪儿??String dest = "Regex02.java";//调用方法实现文件复制method4(src,dest);}//基本字符流一次读写一个字符pu...

weixin_39754267的博客 97

数组复制的五种方式(遍历循环一一赋值、System.arraycopy、地址赋值、克隆clone()、Arrays.copyof())...

package com.Summer_0424.cn; import java.util.Arrays; import java.util.concurrent.CopyOnWriteArrayList; /** * @author Summer * 数组复制的五种方式(遍历循环一一赋值、System.arraycopy、地址赋值、克隆clone()、Array.copy...

weixin_34308389的博客 233

javaIO流中字符流的应用

五种方式实现文本文件复制(字符流) * 基本字符流一次读写一个字符 * 基本字符流一次读写一个字符数组 * 高效字符流一次读写一个字符 * 高效字符流一次读写一个字符数组 * 高效字符流一次读写一个字符串 public class FiveKindIO { public static void main(String[] args) throws E...

ZhuCong_2016的博客 175

Java中的I/O

输出流写文件 package Test10; import java.io.FileWriter; import java.io.IOException; /* * FileWriter: * FileWriter(String fileName):传递一个文件名称 * * 输出流写文件的步骤: * 1.创建输出流对象 * ...

lhzzm的博客 228
上一篇: 运算符>>和>>>的区别
下一篇: Java的鲁棒性(Robust)
icankeep
博客等级 码龄9年 11粉丝 76原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值