对象数组的深拷贝

2024-01-27

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

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

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


你所实施的是shallow复制。实施一个deep复制,你必须 改变

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

分配给某些事物copy of other.data[i] to data[i]。如何执行此操作取决于Position班级。可能的替代方案是:

  • 复制构造函数:

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

  • 工厂方法:

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

  • clone:

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

Notes:

  1. 上面假设复制构造函数、工厂方法和克隆方法分别实现“正确”类型的复制,具体取决于 Position 类;见下文。
  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类,我们会假设属性都是原始类型(例如整数或双精度),因此深复制与浅复制是没有意义的。但是如果存在引用属性,那么您必须依赖复制构造函数/工厂方法/克隆方法来执行您需要的那种复制。在每种情况下都需要对其进行编程。并且在一般情况下(必须处理循环)这很困难并且需要每个类实现特殊的方法。

还有另外一个潜在的复制对象数组的方法。如果数组中的对象是可序列化,然后你可以使用复制它们ObjectOutputStream and ObjectInputStream序列化然后反序列化数组。然而:

  • 这个很贵,
  • 它仅在对象可(传递地)序列化时才有效,并且
  • 任何的值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 所说,这并不涉及任何魔法。您(手动)实现一个构造函数,该构造函数通过从现有实例复制来初始化其状态。


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:

"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."

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.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对象数组的深拷贝 的相关文章

随机推荐

  • 什么是 PHP 框架?

    我以前从未听说过这个 而且我已经用 PHP 编码很长一段时间了 我实际上觉得问这个问题有点愚蠢 但是 什么是 PHP 框架 它对我有什么帮助 我该如何使用它 一般来说 框架是一个类和函数的集合 让您更快地实现目标开发中 Symfony Ca
  • 从多维数组中搜索并删除

    如果我的值 ID 等于 1 并搜索一个数组 我希望从数组本身中删除 如果找到的话 ID 为 1 Array 0 gt Array id gt 1 1 gt Array id gt 4 2 gt Array id gt 5 3 gt Arra
  • 填写表格 ms-word VBA / 通过 Word 最有效的智能导航

    Summary 我的公司向客户发送信件 并希望我编写一个宏来填写在 Word 文档中设置的不同文本表单字段 因为发送的不同信件之间的变化非常有限 我在 excel 中做过宏 但这是我第一次遇到 ms word 宏 Problem 我很难通过
  • 如何打包面向通用 Windows 平台的 .NET 库?

    如何以现代通用方式打包通用 Windows 平台库以通过 NuGet 发布 假设我有一个用 C 编写的 AnyCPU 程序集 它导出一些代码和 XAML 用户控件 这是一系列问题和解答 记录了我对现代 NuGet 包创作主题的发现 特别关注
  • setContentView 上的 ViewCompat$OnUnhandledKeyEventListener

    该错误是由以下命令触发的 setContentView R layout activity item list 此代码是由 android studio 在使用 主 从流程 创建新的 android 项目时生成的 看起来布局已渲染 但仍然出
  • 从 Access 获取最后的插入 ID

    我熟悉MySQL函数LAST INSERT ID 是否有类似的函数可以通过 ODBC 对 MS Access 数据库执行相同的查询 在我的具体情况下 我使用 PHP PDO 将行插入 Access 数据库 并且想知道每次插入执行时的最后一个
  • JavaScript mootools 添加事件

    我正在尝试找出我的代码有什么问题 Mootools 核心文件附加到 HTML 头并且运行良好 如果我添加代码 myElement addEvent click function alert clicked 就在 div Click me d
  • exit 在这个 ruby​​ if fork 块中做什么

    一些代码如下 def start if fork do something exit 0 end end fork 复制一个子进程 我说得对吗 但我的问题是哪个进程做了exit 0真的退出吗 父进程还是子进程 fork http ruby
  • 使用 Javascript 的递归方法[重复]

    这个问题在这里已经有答案了 我正在尝试复制 json stringify 方法 但使用递归 我已经能够通过很多测试用例 但是当涉及到嵌套数组时 我似乎遇到了问题 如果数组内有任何空数组 我会得到类似 7 9 而不是 7 9 的内容 另外 如
  • 在 C 中创建字符串堆栈

    我想要一个接受字符串的堆栈 我希望能够推入和弹出字符串 以及清除整个堆栈 我认为 C 有一些方法可以做到这一点 那么C呢 未经测试的快速示例 采用单链表结构 元素被推入列表头部或从列表头部弹出 include
  • 将工作表传递给函数(excel vba)

    我一直在尝试将工作簿中的一张工作表传递给函数 但它似乎不起作用 函数是 Private Sub passToSheet theData As Variant Optional mySheet As Worksheet 我试过做 Dim my
  • 从 azure 部署的机器人向 MS 团队发送主动消息

    我已经将机器人部署到 azure 当连接到 azure 中的 MS 团队频道时 我能够 ping 机器人并接收消息 这很好 我还在机器人中添加了主动消息传递 其中通道中每隔一分钟就会触发一条消息 它在模拟器中工作 但在网络聊天和 MS 团队
  • 相当于 R 中的“this”或“self”

    我正在寻找 R 中 python 的 self 关键字或 java 的 this 关键字的等效项 在下面的示例中 我从另一个 S4 对象的方法创建一个 S4 对象 并且需要将一个指针传递给我自己 该语言中有什么东西可以帮助我做到这一点吗 M
  • 在django中扩展User模型后,如何创建ModelForm?

    我扩展了 django 中的用户模型以包含其他几个变量 例如位置和雇主 现在我正在尝试创建一个具有以下字段的表单 First name from User Last name from User Location from UserProf
  • WebAuthN 是否可以查看可用的平台验证器?

    我的任务是为 webauthn 创建自定义注册屏幕 我们想要向用户展示faceid将用于验证他们的身份 或者他们的指纹将被使用 拥有设备表并从中派生的解决方案似乎是一场可持续发展的噩梦 我更愿意从 navigator credentials
  • 使用 OIDC 在每个 API 请求中发送哪些信息

    I m writing an API back end that I want to use OpenID Connect OIDC to secure I ve been reading the documentation but I m
  • 使用 Angular 在 Firebase 中保存结构化数据

    我了解储蓄的概念和最佳实践结构化数据 https www firebase com docs web guide structuring data html在 firebase 中 但我不清楚如何将数据实际保存到多个位置并提供所需的交叉引用
  • 使用 R 映射博客之间的链接网络?

    我想了解有关如何创建和可视化博客之间的链接图以反映它们之间的 社交网络 的建议 这是我的想法 从一个 或多个 博客主页开始 收集该页面上的所有链接 删除所有属于内部链接的链接 也就是说 如果我从 www website com 开始 那么我
  • UIViewController 内的 PullToRefresh TableView

    我有一个UI视图控制器这也是UITableViewDelegate 除其他外 对于UI表格视图 在 FirstView xib 中创建 interface FirstViewController UIViewController lt UI
  • 对象数组的深拷贝

    我想使用构造函数制作对象数组的深层副本 public class PositionList private Position data new Position 0 public PositionList PositionList othe