【Java基础知识 4】秒懂数组拷贝,感知新境界

本文介绍了Java中数组拷贝的方法,包括System.arraycopy和Arrays.copyOf的使用,详细讲解了基本类型和对象数组的浅拷贝。同时讨论了数组起始索引为0的原因以及clone()方法在数组拷贝中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、前言

二、为什么数组的起始索引是0而不是1?

三、起别名

四、System.arraycopy与Arrays.copyOf(浅拷贝)

1、基本类型数组复制

2、Object数组复制

3、多维数组复制

4、对象数组复制

五、clone()

1、基本数组类型clone()

2、对象数组clone()


一、前言

最近遇到了数组拷贝的问题,之前从来都没想过,数组居然还用拷贝?

小编在今天之前,用的都是循环赋值的方式进行数组拷贝,速度将对较慢,代码看起来很low,不推荐使用。

今天就这个机会,总结一波,分享给大家。

二、为什么数组的起始索引是0而不是1?

这个习惯来源于机器语言,那时要计算一个数组元素的地址需要将数组的起始地址加上该元素的索引。将起始索引设为1要么浪费数组的第一个元素的空间,要么会花费额外的时间来将索引减1。

三、起别名

数组名表示的是整个数组,如果我们将一个数组变量赋予给另一个变量,那么两个变量都将会指向同一个数组。

public class Test01 {
    public static void main(String[] args) {
        int[] arr = new int[3];
        arr[0] = 0;
        arr[1] = 1;
        arr[2] = 2;
        int[] arr2 = arr;
        arr2[2] = 22;
        System.out.println(arr[2]);//输出22
    }
}

这种情况叫作起别名,有时可能会导致难以察觉的问题。如果你是想将数组复制一份,那么应该声明、创建并初始化一个新的数组,然后将原数组中的元素挨个复制到新数组。

四、System.arraycopy与Arrays.copyOf(浅拷贝)

这个是System提供的方法,也是我推荐的一种拷贝方式,它是浅拷贝,对非基本类型而言,它拷贝的是对象的引用,而不是去新建一个新的对象,这个方法不是Java写的,底层是用C或C++实现的,速度比较快。

通过源码分析,Arrays.copyOf是一个浅拷贝。

public static byte[] copyOfRange(byte[] original, int from, int to) {                   
   int newLength = to - from;
   if (newLength < 0)
       throw new IllegalArgumentException(from + " > " + to);
       byte[] copy = new byte[newLength];
       System.arraycopy(original, from, copy, 0,
              Math.min(original.length - from, newLength));
        return copy;
    }

实际上它调用的还是System.arraycopy,所以它也是浅拷贝。

1、基本类型数组复制

package com.guor.test.javaSE.collection;
 
import java.util.Arrays;
 
import com.guor.test.User;
 
public class ArrayTest {
 
	public static void main(String[] args) {
		beanCopy();
	}
	
	//**************************************************************
	private static void copySelf() {
		int[] ids = { 1, 2, 3, 4, 5 };  
		System.out.println(Arrays.toString(ids));
		//System.arraycopy(src, srcPos, dest, destPos, length);
		// 把从索引0开始的2个数字复制到索引为3的位置上  
		System.arraycopy(ids, 0, ids, 3, 2);
		System.out.println(Arrays.toString(ids));//[1, 2, 3, 1, 2]
	}
	
	private static void copyToOther() {
		int[] ids = { 1, 2, 3, 4, 5 };  
		//将数据的索引1开始的3个数据复制到目标的索引为0的位置上  
		int[] other = new int[5];
		System.arraycopy(ids, 1, other, 0, 3);
		System.out.println(Arrays.toString(ids));//[1, 2, 3, 4, 5]深复制
		System.out.println(Arrays.toString(other));//[2, 3, 4, 0, 0]
	}
}

2、Object数组复制

//如果是类型转换问题,获取整形
private static void getIntegerArrayFromObjectArray() {
    Object[] obj1 = { 1, 2, 3, "4", "5" };
    Integer[] obj2 = new Integer[5];

    try {
        System.arraycopy(obj1, 0, obj2, 0, obj1.length);
    } catch (Exception e) {
        System.out.println("transfer exception:"+e);
    }
    System.out.println(Arrays.toString(obj1));
    System.out.println(Arrays.toString(obj2));
}

//获取Object数组中的字符串类型数据
private static void getStringArrayFromObjectArray1() {
    Object[] obj3 = { 1, 2, 3, "4", "5" };
    String[] obj4 = new String[5];
    try {
        System.arraycopy(obj3, 2, obj4, 2, 3);
    } catch (Exception e) {
        //transfer exception:java.lang.ArrayStoreException
        System.out.println("transfer exception:"+e);
    }
    System.out.println(Arrays.toString(obj3));
    //[null, null, null, null, null]
    System.out.println(Arrays.toString(obj4));
}

//获取Object数组中的字符串类型数据
private static void getStringArrayFromObjectArray2() {
    Object[] obj3 = { 1, 2, 3, "4", "5" };
    String[] obj4 = new String[5];
    try {
        System.arraycopy(obj3, 3, obj4, 3, 2);
    } catch (Exception e) {
        System.out.println("transfer exception:"+e);
    }
    System.out.println(Arrays.toString(obj3));
    //[null, null, null, 4, 5]
    System.out.println(Arrays.toString(obj4));
    obj3[3] = "zhangssan";
    System.out.println("查看是浅复制还是深复制~~~~~");
    System.out.println(Arrays.toString(obj3));
    System.out.println(Arrays.toString(obj4));
}

3、多维数组复制

//多维数组
public static void twoArray() {
    int[] arr1 = {1, 2};
    int[] arr2 = {3, 4};
    int[] arr3 = {5, 6};

    int[][] src = new int[][]{arr1, arr2, arr3};

    print("原始模样:", src);
    int[][] dest = new int[3][];
    System.arraycopy(src, 0, dest, 0, 3);

    System.out.println("改变前");
    print("src = ", src);
    print("dest = ", dest);

    //原数组改变后观察新数组是否改变,改变->浅复制,不改变->深复制
    src[0][0] = -1;

    System.out.println("改变后");
    print("src = ", src);
    print("dest = ", dest);
}

4、对象数组复制

//对象复制
private static void beanCopy() {
    User user1 = new User("zs",18);
    User user2 = new User("ls",18);
    User user3 = new User("ww",18);
    User[] userArraySrc = {user1, user2, user3};
    User[] userArrayDest = new User[3];
    System.out.println("对象复制,原始模样:"+Arrays.toString(userArraySrc));
    System.arraycopy(userArraySrc, 0, userArrayDest, 0, userArraySrc.length);
    System.out.println("userArrayDest," + Arrays.toString(userArrayDest));
    System.out.println("------------改变原对象------------------");
    userArraySrc[0] = new User("su",20);
    System.out.println("***" + Arrays.toString(userArraySrc));
    System.out.println("***" + Arrays.toString(userArrayDest));
}

//二维数组toString()
private static void print(String string, int[][] arr) {
    System.out.print(string);
    for (int[] a : arr) {
        for (int i : a) {
            System.out.print(i + " ");
        }
        System.out.print(",");
    }
    System.out.println();
}

五、clone()

protected native Object clone() throws CloneNotSupportedException;

clone()也是native方法,所以也是C语言实现的。

1、基本数组类型clone()

2、对象数组clone()

上一篇:【Java基础知识 3】为何要配置环境变量?

下一篇:【Java基础知识 5】装箱和拆箱

评论 59
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值