当前位置: 首页 > 面试题库 >

对象数组的深层副本

刘野
2023-03-14
问题内容

我想使用构造函数制作对象数组的深层副本。

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];
            }

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


问题答案:

您已实现的是 浅表 副本。要实现 深度 复制,您必须进行更改

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

一些事情,分配一个 副本other.data[i]data[i]。您如何执行此操作取决于Position班级。可能的替代方法是:

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()方法)的本地实现会进行浅表复制。

实际上,在Java中实现深度复制的一般问题很复杂。在Position类的情况下,将假定属性都是原始类型(例如int或double),因此,浅层复制与深层复制无关紧要。但是,如果有引用属性,则必须依靠复制构造函数/工厂方法/克隆方法来进行所需的复制。在每种情况下,都需要对其进行编程。在一般情况下(必须处理循环),这很困难,并且需要每个类实现特殊的方法。

还有另一种 可能的 方法可以复制对象数组。如果数组中的对象是可 序列化的
,则可以使用ObjectOutputStreamObjectInputStream序列化然后再反序列化数组来复制它们。然而:

  • 这很贵
  • 它仅在对象(可传递)可序列化时起作用,并且
  • 任何transient字段的值都不会被复制。

不建议通过序列化进行复制。支持克隆或其他方法会更好。

总而言之,在Java中最好避免深层复制。

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

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

正如@Turtle所说的,没有任何魔术。您将实现一个构造函数(手动),该构造函数通过从现有实例复制来初始化其状态。



 类似资料:
  • 问题内容: 我有一个叫Meal的课程 而且我有很多餐: 我想复制该数组,然后在其中一个实例中对Meal实例进行一些更改,而在第二个实例中不更改Meal实例,我将如何对其进行深拷贝? 问题答案: 由于是一个快速数组,所以该语句 将有效地复制原始数组。 但是,由于Meal是一 类 ,因此新数组将包含对原始膳食中相同膳食的引用。 如果您也想复制进餐内容,那么在一个数组中更改进餐不会在另一个数组中更改进餐

  • 问题内容: 实现深层对象复制功能有点困难。您采取什么步骤来确保原始对象和克隆对象没有引用? 问题答案: 一种安全的方法是序列化对象,然后反序列化。这样可以确保所有内容都是全新的参考。 这是有关如何有效执行此操作的文章。 注意事项:类可能会覆盖序列化,这样就不会创建新实例,例如单例。如果您的课程不是可序列化的,那么这当然也行不通。

  • 问题内容: 我需要一个从任何参数构建JSON有效字符串的函数,但: 通过不两次添加对象来避免递归问题 通过截断给定深度来避免调用堆栈大小问题 通常,它应该能够处理大对象,但要以截断为代价。 作为参考,此代码失败: 避免递归问题很简单: 但是到目前为止,除了复制和更改Douglas Crockford的代码 以跟踪深度之外,我还没有找到任何方法来避免在诸如或any之类的非常深的对象上发生堆栈溢出。有

  • 问题内容: 我有一个不同的numpy数组的numpy数组,我想对数组进行深层复制。我发现以下内容: d是执行此操作的最佳方法吗?我错过了深层复制功能吗?与大小不同的数组中的每个元素进行交互的最佳方法是什么? 问题答案: 请随时在此处阅读更多内容。 哦,这是最简单的测试用例:

  • 问题内容: 根据JAVA文档,当调用super.clone()时,将返回对象的浅表副本。在下面的代码中,我有两个对象 name 和 id ;和一个基本变量 num 。当在第一个对象上调用super.clone()方法时,除了预期的num副本外,它似乎还在创建对象的深层副本(名称和ID)。克隆对象obj之后,我更改了它的名称和id字段。如果正在制作浅表副本,则这些更改应反映在克隆的对象中。我对吗?

  • 我有一个对象数组,如下所示; 我想把它转换成下面的对象 在Javascript或Angular 4中有没有同样的方法?