简体   繁体   English

参考、浅拷贝和深拷贝

[英]Reference, Shallow, and Deep Copy

I have been researching and reading what these three (Reference copy, Shallow copy and Deep copy) methods do and how to create them;我一直在研究和阅读这三种(参考复制、浅复制和深复制)方法的作用以及如何创建它们; and I am still having a hard time understanding how to implement the said methods in my code.我仍然很难理解如何在我的代码中实现上述方法。

The first method suppose to be a reference method (refCopy), the second should be a shallow method (shalCopy) and last a deep copy method(deepCopy).第一个方法假设是引用方法(refCopy),第二个方法应该是浅方法(shalCopy),最后一个方法是深复制方法(deepCopy)。 Not sure if these are correct.不确定这些是否正确。 Any help on how to execute these copies correctly will be greatly appreciated.任何有关如何正确执行这些副本的帮助将不胜感激。

This is my code so far:到目前为止,这是我的代码:

public class ArrayRefCopy implements Cloneable {
    private static int n = 3;
    private static StringBuffer[] buf = new StringBuffer[4];
    public static void main(String[] args){

        StringBuffer[] hel = new StringBuffer[n];
        hel[0] = new StringBuffer("hello");
        hel[1] = new StringBuffer("hallo");
        hel[2] = new StringBuffer("hey");

        refCopy(hel);
        System.out.println(Arrays.toString(hel));
        shalCopy(hel);
        System.out.println(Arrays.toString(hel));


    }

    public static StringBuffer[] refCopy(StringBuffer[] bra){

        StringBuffer[] ber = bra;
        return ber;
    }

    public static StringBuffer[] shalCopy(StringBuffer[] bar){

        return buf = bar;
    }

    public static StringBuffer[] deepCopy(StringBuffer[] bri){

        StringBuffer[] deep = new StringBuffer[n];
        return deep = bri.clone();
    }
}

========================================================================= ================================================== ========================

I changed the last two methods to this (created objects in them):我将最后两个方法更改为此(在其中创建对象):

public static StringBuffer[] shalCopy(StringBuffer[] bar){
        StringBuffer[] buf = new StringBuffer[n];
        return buf = Arrays.copyOf(bar, n);
    }

    public static StringBuffer[] deepCopy(StringBuffer[] bri){

        StringBuffer[] deep = new StringBuffer[n];
        return deep = bri.clone();
    }

But when I do this:但是当我这样做时:

StringBuffer[] hel = new StringBuffer[n];
        hel[0] = new StringBuffer("hello");
        hel[1] = new StringBuffer("hallo");
        hel[2] = new StringBuffer("hey");

        StringBuffer[] hal = new StringBuffer[n];
        hal = deepCopy(hel);


        System.out.println(hal.equals(hel));

It gives me false.它给我虚假。 I thought clone would completely copy the object with its values.我认为 clone 会完全复制对象及其值。 Why is it giving me false?为什么它给我虚假?

UPDATE:更新:

public static StringBuffer[] shalCopy(StringBuffer[] bar){
        StringBuffer[] buf = new StringBuffer[bar.length];
        for(int i = 0; i < bar.length; i++){
            buf[i] = bar[i];
        }

            return buf;
        }




    public static StringBuffer[] deepCopy(StringBuffer[] bri){

        StringBuffer[] deep = new StringBuffer[bri.length];
        for(int i=0; i < bri.length; i++){
            bri[i] = new StringBuffer(bri[i]);
            deep[i] = bri[i];
        }

        return deep;

    }

Your refCopy() is fine. 您的refCopy()很好。

shalCopy() needs to construct a new array, then copy in the input StringBuffer references so it shares those StringBuffer objects. shalCopy()需要构造一个new数组,然后在输入StringBuffer引用中进行复制,以便共享这些StringBuffer对象。 Write a loop or use arrayCopy . 编写循环或使用arrayCopy

deepCopy() needs to construct a new array and then make copies of all the input StringBuffers . deepCopy()需要构造一个new数组,然后复制所有输入StringBuffers

Can you fill in the details? 您可以填写详细信息吗? If we do your assignment for you, you might not learn from it as well. 如果我们为您完成任务,您可能也不会从中学习。

Update: Your updated shalCopy() method gets the right result in this case but (1) it should use bar.length (its input array length) instead of assuming its input array has length n , and (2) the first assignment buf = new StringBuffer[n] is pointless and misleading since the code immediately replaces that with another array. 更新:在这种情况下,更新的shalCopy()方法可获得正确的结果,但(1)应该使用bar.length (其输入数组的长度),而不是假设其输入数组的长度为n ,以及(2)第一个赋值buf = new StringBuffer[n]是毫无意义的并且具有误导性,因为代码立即将其替换为另一个数组。 Also, this will be more instructive if you write an explicit loop rather than call Arrays.copyOf() . 此外,如果您编写一个显式循环而不是调用Arrays.copyOf() ,则这将更具启发性。

Your updated deepCopy() does not get the right result, and it repeats the above problems. 您更新的deepCopy()无法得到正确的结果,并且会重复上述问题。 clone() is not what's needed, is not so useful in general, and does not shed any light on the problem at hand, that is, it's not instructive here. clone()并不是必需的,一般来说它并不是那么有用,并且也不能说明当前的问题,也就是说,这里没有启发性。 Instead, try constructing a new array and using a loop to (deep) copy all the StringBuffer objects, not their references. 而是尝试构造一个新数组,并使用循环来(深度)复制所有StringBuffer对象,而不是它们的引用。

Here's how you can tell if your code works: 您可以通过以下方式判断代码是否有效:

  • A reference copy dest = refCopy(source) should make the variable dest refer to the same instance as source . 参考副本 dest = refCopy(source)应该使变量dest引用与source相同的实例。 So changing eg dest[0] = null will also change source[0] . 因此,更改例如dest[0] = null也会更改source[0]
  • A shallow copy dest = shalCopy(source) should make the variable dest refer to a new array that contains the very same instances that are in source . 浅表复制 dest = shalCopy(source)应该使变量dest引用一个新数组,该数组包含与source相同的实例。 So changing dest[0] = null will not change source[0] , but modifying a shared instance, eg dest[1].append("!") will modify source[1] . 因此,更改dest[0] = null不会更改source[0] ,但是修改共享实例,例如dest[1].append("!")将修改source[1]
  • A deep copy dest = deepCopy(source) should make the variable dest refer to a separate array that contains separate instances that are not in source . Deep copy dest = deepCopy(source)应该使变量dest引用一个单独的数组,该数组包含不在source中的单独实例。 So neither of the above changes to dest will modify source . 因此,以上对dest更改均不会修改source

Reference copy = A new variable pointing to the original object. 参考副本=指向原始对象的新变量。

Shallow copy = Create a new copy of the original object and assign identical values to its primitive properties but use the same references as the original object for the properties that refer to other objects. 浅拷贝=创建原始对象的新副本,并为其原始属性分配相同的值,但对于引用其他对象的属性,使用与原始对象相同的引用。

Deep copy = Create a new copy of the original object and recursively create new copies for every object reference in the original object references chain. 深度复制=创建原始对象的新副本,并为原始对象引用链中的每个对象引用递归创建新副本。

Example: 例:

class C {
int b;
A ref1; // in shallow copy, use the same object reference. In deep copy, create a copy on this class instance
}

To answer your second question on why hal.equals(hel) returns false: It's because this is the same as == check. 要回答关于hal.equals(hel)为什么返回false的第二个问题:这是因为它与== check相同。 To compare two arrays contents, you'd have to use Arrays.equals(array1, array2); 要比较两个数组的内容,您必须使用Arrays.equals(array1, array2);

你的答案在这里:参考副本、浅副本和深副本https://medium.com/swlh/reference-copy-shallow-copy-and-deep-copy-63f9418c9c51

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM