对象数组的深拷贝 [英] Deep copy of an object array

查看:42
本文介绍了对象数组的深拷贝的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用构造函数对对象数组进行深拷贝.

I want to make a deep copy of an object array using a constructor.

public class PositionList {
    private Position[] data = new Position[0];

public PositionList(PositionList other, boolean deepCopy) {
        if (deepCopy){
            size=other.getSize();
            data=new Position[other.data.length];
            for (int i=0;i<data.length;i++){
            data[i]=other.data[i];
            }

但是,由于某种原因,我上面的内容不起作用.我运行了自动化测试,但这些测试失败了.所以这里有一个错误,我不确定它是什么.

However, what I have above for some reason is not working. I have automated tests that I run, and its failing those tests. So theres an error an here that Im not sure what it is.

推荐答案

您实施的是浅层副本.要实现复制,您必须改变

What you have implemented is a shallow copy. To implement a deep copy, you must change

data[i] = other.data[i];

other.data[i]copy 分配给data[i].您如何执行此操作取决于 Position 类.可能的替代方法是:

to some thing that assigns a copy of other.data[i] to data[i]. How you do this depends on the Position class. Possible alternatives are:

  • 复制构造函数:

  • a copy constructor:

data[i] = new Position(other.data[i]);

工厂方法:

data[i] = createPosition(other.data[i]);

克隆:

data[i] = (Position) other.data[i].clone();

注意事项:

  1. 上面假设复制构造函数、工厂方法和克隆方法分别实现了正确"的方法.复制类型,取决于 Position 类;见下文.
  2. clone 方法只有在 Position 明确支持它的情况下才有效,这通常被认为是一种劣质的解决方案.此外,您需要注意clone 的本机实现(即Object.clone() 方法)执行浅拷贝1.
  1. The above assume that the copy constructor, factory method and clone method respectively implement the "right" kind of copying, depending on the Position class; see below.
  2. The clone approach will only work if Position explicitly supports it, and this is generally regarded as an inferior solution. Besides, you need to be aware that the native implementation of clone (i.e. the Object.clone() method) does a shallow copy1.

实际上在Java中实现深度复制的一般问题是复杂的.在 Position 类的情况下,人们会假设属性都是原始类型(例如整数或双精度数),因此深拷贝与浅拷贝没有实际意义.但是如果有引用属性,那么你必须依靠复制构造函数/工厂方法/克隆方法来做你需要的那种复制.在每种情况下都需要对其进行编程.而在一般情况下(您必须处理循环),这很困难并且需要每个类实现特殊方法.

In fact the general problem of implementing deep copying in Java is complicated. In the case of the Position class, one would assume that the attributes are all primitive types (e.g. ints or doubles), and therefore a deep versus shallow copying is moot. But if there are reference attributes, then you have to rely on the copy constructor / factory method / clone method to do the kind of copying that you require. In each case it needs to be programmed in. And in the general case (where you have to deal with cycles) it is difficult and requires each class to implement special methods.

还有另一种潜在方法来复制对象数组.如果数组中的对象是可序列化,那么您可以通过使用ObjectOutputStreamObjectInputStream 序列化然后反序列化数组来复制它们.然而:

There is one other potential way to copy an array of objects. If the objects in the array are serializable, then you can copy them by using ObjectOutputStream and ObjectInputStream serialize and then deserialize the array. However:

  • 这很贵,
  • 它仅在对象是(可传递的)可序列化时才有效,并且
  • 不会复制任何 transient 字段的值.
  • this is expensive,
  • it only works if the objects are (transitively) serializable, and
  • the values of any transient fields won't be copied.

不推荐通过序列化复制.最好支持克隆或其他方法.

Copying by serialization is not recommended. It would be better to support cloning or some other method.

总而言之,Java 中最好避免深度复制.

All in all, deep copying is best avoided in Java.

最后,要回答您关于 Position 类复制构造函数的问题,我希望它是这样的:

Finally, to answer your question about the Position classes copy constructor works, I expect it is something like this:

public class Position {
    private int x;
    private int y;
    ...
    public Position(Position other) {
        this.x = other.x;
        this.y = other.y;
    }
    ...
}

正如@Turtle 所说,不涉及魔法.您实现了一个构造函数(手动),该构造函数通过从现有实例复制来初始化其状态.

As @Turtle says, there's no magic involved. You implement a constructor (by hand) that initializes its state by copying from an existing instance.

1 - 指定 clone() 的对象实现进行浅拷贝,但这可能会被覆盖.clone 的 javadoc 指定了合同".如下:

1 - It is specified that the Object implementation of clone() does a shallow copy, but this may be overridden. The javadoc for clone specifies the "contract" as follows:

"创建并返回此对象的副本.复制"的确切含义可能取决于对象的类.一般意图是,对于任何对象 x,表达式:x.clone() != x 将为真,并且表达式:x.clone().getClass()== x.getClass() 为真,但这些并不是绝对的要求.虽然通常的情况是:x.clone().equals(x) 为真,但这不是绝对要求."

"Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object. The general intent is that, for any object x, the expression: x.clone() != x will be true, and that the expression: x.clone().getClass() == x.getClass() will be true, but these are not absolute requirements. While it is typically the case that: x.clone().equals(x) will be true, this is not an absolute requirement."

合同"中没有任何内容谈论深复制与浅复制.因此,如果您打算在此上下文中使用 clone,您需要了解实际类 clone 方法的行为.

Nothing in the "contract" talks about deep versus shallow copying. So if you are going to use clone in this context, you need to know how the actual classes clone method behaves.

这篇关于对象数组的深拷贝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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