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

arraylist的副本不断修改为原始值

丁震博
2023-03-14
问题内容

我正在使用一个用于保存和调用屏幕状态的系统,这是我第一次弄这种东西,所以我不确定如何解决此问题的最佳方法是什么,但是我目前存储了所有“
PreviewMonitor”数组列表中的对象(大约40个左右)。问题是,当我创建要存储的名为“
allPreviewMonitors”的ArrayList的副本时,最终得到的ArrayList的元素随着原始元素的更新而不断变化。实际上,好像我正在使用原始ArrayList一样,当我创建allPreviewMonitors的副本时,它应该是一个完全不同的ArrayList,其中包含元素及其状态的“冻结”版本。为什么会发生这种现象?如果需要的话,我可以显示代码,但是我不确定这里是否需要它。


问题答案:

您仅将对象引用复制到ArrayList中。您需要复制对象本身。

在Java中,所有对象变量实际上都是引用变量。所以代码:

Myclass myObject = new Myclass();
Myclass otherObject = myObject;

创建MyClass对象,并将对该Myclass对象的引用存储在引用变量中myObject。然后,它创建一个新的参考变量otherObject,并将参考数据(例如,内存地址)从复制myObjectotherObject。现在,它们引用内存中的同一对象。此时,线

myObject.myMethod();

具有与以下相同的结果

otherObject.myMethod();

您在ArrayList中得到的是对相同对象的不同引用。您想要的是以下之一:

Myclass otherObject = myObject.clone(); // use the clone function
// OR
Myclass otherObject = new Myclass(myObject); // use a copy constructor

如果使用clone()或副本构造函数将对象放入ArrayList ,则ArrayList将包含对相同副本的引用,而不是对相同副本的引用。

正如其他人指出的那样,仅复制引用的副本称为“浅副本”,而复制所引用的对象的副本称为“深副本”。

编辑:为了使此方法有效,您的解决方案不仅要在 您的
类上实现,而且还必须在您类中包含的所有类上实现。例如,考虑MyClass哪个具有类型的字段OtherClass

class MyClass {
  private String foo;
  private OtherClass bar;
  private int x;
  MyClass(String f, OtherClass b, int x) {
    foo = f;
    bar = b;
    this.x = x;
  }

  MyClass(MyClass o) {
    //make sure to call the copy constructor of OtherClass
    this(new String(o.foo), new OtherClass(o.bar), o.x);
  }
  // getters and setters
}

请注意,这OtherClass还需要一个副本构造函数!而且,如果OtherClass引用其他类,那么它们也需要复制构造函数。没有办法解决。

最后,您的列表副本将如下所示:

List<MyClass> myNewList = new ArrayList<>(myExistingList.size());
for ( MyClass item : myExistingList) {
  // use the copy constructor of MyClass, which uses the copy constructor of OtherClass, etc, etc.
  myNewList.add(new MyClass(item))
}


 类似资料:
  • 在的情况下,将检索添加的元素。在的情况下,方法调用对所传递的字符串没有影响。JVM到底在做什么?有人能详细解释一下吗?

  • 问题内容: 我要复制到 是一组对象。我正在根据某些条件进行修改。问题是,如果我修改,它也会被修改。 问题答案: 显然,您对声明的功能有一些误解。 在JavaScript中,对象是通过引用传递和分配的(更准确地说是引用的值),所以和都是对同一对象的引用。 这是一个简化的插图,可以帮助您可视化正在发生的事情 如您在分配后所看到的,两个引用都指向同一对象。 如果需要修改一个而不是另一个,则需要 创建一个

  • 问题内容: public class StackOverFlow { public static void main(String[] args) { ArrayList al = new ArrayList (); al.add(“A”); al.add(“B”); markAsNull(al); System.out.println(“ArrayList elements are “+al);

  • 我正在C中实现合并排序。我有一个合并函数-和一个mergeSort函数-。 如果对原始数组的前半部分和后半部分进行排序(例如:),则合并排序可以很好地工作。这是因为我的merge函数无论在什么情况下都要传递原始数组,并且当它被赋予2个排序数组时(正如预期的那样),它可以工作。我的问题是他们什么时候不是。每次调用merge时,我的原始数组都没有被修改,尽管我已经对它进行了编程。有人能知道我的问题在哪

  • 我需要计算我的原始HTTP post请求的散列,并将其与Java中相同的头中的签名散列进行比较。问题是,我尝试了多种方法,但无法提取发送的准确POST请求。随函附上请求: 我需要完全相同的字符串(连同所有的%和其他符号),因为即使是一个单独的空格差会生成一个不正确的散列。我们可以在这里使用自定义过滤器吗?如果可以,那么具体如何使用?

  • 问题内容: 我正在用Java创建一个多线程聊天。当用户u1向用户u2发送消息但未连接用户u2时,用户u1将消息发送至服务器,而用户u2一旦连接至服务器,便会收到该消息。未发送的消息将添加到ArrayList中。连接用户后,他会检查自己是否是未决邮件的收件人。如果是,则将邮件发送给他,然后将其从待处理邮件列表中删除。这是我的方法: 这就是我得到的: 我如何解决它?是因为我正在使用迭代器吗? 问题答案