参考,浅和深拷贝

时间:2015-05-25 17:34:12

标签: java arrays methods deep-copy stringbuffer

我一直在研究和阅读这三种方法(参考拷贝,浅拷贝和深拷贝)方法以及如何创建它们;我仍然很难理解如何在我的代码中实现所述方法。

第一种方法假设是参考方法(refCopy),第二种方法应该是浅层方法(shalCopy),最后是深层复制方法(deepCopy)。不确定这些是否正确。任何有关如何正确执行这些副本的帮助将不胜感激。

到目前为止,这是我的代码:

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();
    }
}

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

我将最后两个方法改为此(在其中创建了对象):

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();
    }

但是当我这样做时:

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));

它让我虚伪。我以为克隆会用它的值完全复制对象。为什么它给我假?

更新

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;

    }

2 个答案:

答案 0 :(得分:2)

您的refCopy()没问题。

shalCopy()需要构造一个new数组,然后复制输入StringBuffer引用,以便它共享那些StringBuffer个对象。写一个循环或使用arrayCopy

deepCopy()需要构建一个new数组,然后复制所有输入StringBuffers

你能填一些细节吗?如果我们为您完成任务,您可能也不会从中学习。

更新:在这种情况下,您更新的shalCopy()方法获得了正确的结果,但(1)它应该使用bar.length(其输入数组长度)而不是假设其输入数组的长度为n,(2)第一个赋值buf = new StringBuffer[n]毫无意义且具有误导性,因为代码会立即将其替换为另一个数组。此外,如果您编写显式循环而不是调用Arrays.copyOf(),这将更有启发性。

您更新的deepCopy()无法获得正确的结果,并且会重复上述问题。 clone()不是所需要的,一般来说不是那么有用,并且没有对手头的问题有所了解,也就是说,这里没有指导意义。相反,尝试构造一个新数组并使用循环来(深度)复制所有StringBuffer对象,而不是它们的引用。

以下是如何判断代码是否有效的方法:

  • 参考副本 dest = refCopy(source)应使变量dest引用与source相同的实例。如此改变dest[0] = null也会更改source[0]
  • 浅层副本 dest = shalCopy(source)应该使变量dest引用包含source中相同实例的新数组。因此,更改dest[0] = null不会更改source[0],而是修改共享实例,例如dest[1].append("!")将修改source[1]
  • 深层复制 dest = deepCopy(source)应该使变量dest引用一个单独的数组,该数组包含不在source中的单独实例。因此,dest的上述更改都不会修改source

答案 1 :(得分:1)

引用副本=指向原始对象的新变量。

浅拷贝=创建原始对象的新副本,并为其原始属性指定相同的值,但对引用其他对象的属性使用与原始对象相同的引用。

Deep copy =创建原始对象的新副本,并为原始对象引用链中的每个对象引用递归创建新副本。

示例:

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

回答关于hal.equals(hel)返回false的原因的第二个问题:它是因为这与==检查相同。要比较两个数组内容,您必须使用Arrays.equals(array1, array2);