Java-实现数组的深层和浅层副本 [英] Java - Implement deep and shallow copy of an array

查看:99
本文介绍了Java-实现数组的深层和浅层副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解Java中浅拷贝与深拷贝的概念. 关于该主题有很多文章和问答,但是每当我尝试在真实的Java代码中实现这些概念时,一切都变得不清楚.

I am trying to understand the concept of shallow vs deep copy in Java. There is a lot of articles and Q&A about this subject, but whenever I try to implement these concepts in a real Java code, everything become unclear to me.

我理解的答案之一是此链接,其中通过以下方式解释了深层复制和浅层复制模式.

One of the answers on which I base my understanding is in this link, where deep and shallow copying are explained via schemas.

在每种情况下,我都会在下面的实施中向您展示:

I will show you below my implementation for each case:

  • 浅拷贝:

我以示例 System.arraycopy()为例,在许多文章中我读到它执行浅表复制(以及 clone 方法)

I took for my example the method System.arraycopy() as I read in many articles that it performs a shallow copy (along with the clone method)

public class Test {

    public static void main(String[] args) {
        NameValue[] instance1 = {
                new NameValue("name1", 1),
                new NameValue("name2", 2),
                new NameValue("name3", 3),
        };
        NameValue[] instance2 = new NameValue[instance1.length];

        // Print initial state
        System.out.println("Arrays before shallow copy:");
        System.out.println("Instance 1: " + Arrays.toString(instance1));
        System.out.println("Instance 2: " + Arrays.toString(instance2));

        // Perform shallow copy
        System.arraycopy(instance1, 0, instance2, 0, 3);

        // Change instance 1
        for (int i = 0; i < 3; i++) {
            instance1[i].change();
        }

        // Print final state
        System.out.println("Arrays after shallow copy:");
        System.out.println("Instance 1: " + Arrays.toString(instance1));
        System.out.println("Instance 2: " + Arrays.toString(instance2));
    }

    private static class NameValue {
        private String name;
        private int value;

        public NameValue(String name, int value) {
            super();
            this.name = name;
            this.value = value;
        }

        public void change() {
            this.name = this.name + "-bis";
            this.value = this.value + 1;
        }

        @Override
        public String toString() {
            return this.name + ": " + this.value;
        }
    }
}

主要方法的执行结果如下:

The result of the execution of the main methods is as follows:

Arrays before shallow copy:
Instance 1: [name1: 1, name2: 2, name3: 3]
Instance 2: [null, null, null]
Arrays after shallow copy:
Instance 1: [name1-bis: 2, name2-bis: 3, name3-bis: 4]
Instance 2: [name1-bis: 2, name2-bis: 3, name3-bis: 4]

此结果与上一个链接的模式一致:

this result is an accordance with the schema of the previous link:

  • 深拷贝:

在本例中,我以方法 Arrays.copyOf()为例,在许多文章中我读到它执行深度复制(以及 Arrays.copyOfRange 方法)

I took for this example the method Arrays.copyOf() as I read in many articles that it performs a deep copy (along with the Arrays.copyOfRange method)

public static void main(String[] args) {
    NameValue[] instance1 = {
            new NameValue("name1", 1),
            new NameValue("name2", 2),
            new NameValue("name3", 3),
    };
    NameValue[] instance2 = new NameValue[instance1.length];

    // Print initial state
    System.out.println("Arrays before deep copy:");
    System.out.println("Instance 1: " + Arrays.toString(instance1));
    System.out.println("Instance 2: " + Arrays.toString(instance2));

    // Perform deep copy
    instance2 = Arrays.copyOf(instance1, 3);

    // Change instance 1
    for (int i = 0; i < 3; i++) {
        instance2[i].change();
    }

    // Print final state
    System.out.println("Arrays after deep copy:");
    System.out.println("Instance 1: " + Arrays.toString(instance1));
    System.out.println("Instance 2: " + Arrays.toString(instance2));
}

其中显示:

Arrays before deep copy:
Instance 1: [name1: 1, name2: 2, name3: 3]
Instance 2: [null, null, null]
Arrays after deep copy:
Instance 1: [name1-bis: 2, name2-bis: 3, name3-bis: 4]
Instance 2: [name1-bis: 2, name2-bis: 3, name3-bis: 4]

如果我们将深层复制逻辑基于先前的架构,则应该是以下结果:

If we base the deep copy logic on the previous schema, this should be the result:

您可能会注意到,main方法的执行结果与上述架构的逻辑不同.

As you may notice, the result of the execution of the main method is different from the logic of the schema above.

欢迎任何解释.

推荐答案

我试图理解Java中浅拷贝与深拷贝的概念.

I am trying to understand the concept of shallow vs deep copy in Java.

在Java中,您传递并存储对对象的引用,而不是对象本身.
因此,当您有一个NameValue[] array时,该数组不包含对象NameValue,而是对这些对象的引用.
因此,当您对NameValue[] array2进行浅表复制时,这意味着您只是将引用从一个数组复制到另一个数组.这实际上意味着,现在arrayarray2都引用完全相同的对象,并且您对array[2]所做的任何更改都将在array2[2](相同的对象)中可见.

In Java you pass around and store references to objects not the objects themselves.
So when you have an NameValue[] array the array does not contain the objects NameValue but references to the objects.
So when you do a shallow copy to NameValue[] array2 it means you are just copying the references from one array to the other. Which effectively means that now both array and array2 refer to exactly the same objects and any change you do from array[2] will be visible from array2[2] (same object).

深度复制时,将每个对象完全复制到另一个存储区,并在新数组中保留对该新对象的引用.
这样,两个数组现在引用了不同的对象,并且array2[2]

When you deep copies you copy each object completely to another memory area and you keep a reference to that new object in your new array.
This way the 2 arrays now refer to different objects and any change to array[2] are not visible from array2[2]

更新:
这不适用于确实存储实际值而不是引用的基元.
因此,int[] a在复制时会得到值的副本(即某种意义上的深层副本),因为a[2]包含值本身而不是对值的引用.

Update:
This does not apply to primitives that do store the actual value and not a reference.
So an int[] a when you copy you get a copy of the values (i.e. deep copy in a sense) because a[2] contains the value itself and not the reference to the value.

这篇关于Java-实现数组的深层和浅层副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆