【问题标题】:how to copy an object without changing the orignial - java如何在不更改原始对象的情况下复制对象 - java
【发布时间】:2015-09-16 09:11:19
【问题描述】:

我是java的初学者。在为一个小项目编写代码时,我偶然发现了一个问题,经过多次尝试我仍然无法解决。 我有一个只存储二维数组的小类:

class Board{
    int[][] Field;

    Board(int[][] field){
      Field=field;
    }

    Board(Board Test){
      this.Field=Test.Field;
    }

    public void change(int x, int y, int number){
      Field[y][x]=number;
    }

    public void Print(){
      System.out.println(Arrays.toString(Field[0]);
      System.out.println(Arrays.toString(Field[1]);
      System.out.println(Arrays.toString(Field[2]);
    }
}

我的意图如下:

  1. 使用 testarray 创建一个对象 Test1。
  2. 创建一个对象 Test2,它具有来自 Test1 的 testarray 的独立副本。
  3. 在 Test2 的 testarray 上更改一些内容。

我尝试了以下代码:

public static void main(String[] args) {

  int[][] testarray={ {0,0,0},
                      {0,0,0},
                      {0,0,0}};

  Board Test1=new Board(testarray);    //creates the object Test1 with the testarray
  Board Test2=new Board(Test1);        //creates the object Test2 with the object Test 1 as model
  Test2.change(1,1,1);                 //changes something on the array of Test 2
  Test2.Print();                       //prints the array of Test2
  Test1.Print();                       //prints the array of Test1 
}

但是当我执行代码时,对象 Test1 的数组的更改方式与我更改对象 Test 2 的数组的方式完全相同!我已经在这个论坛上搜索过,发现很多类似的帖子。也有各种想法如何解决这个问题,但我尝试了很多(使用方法 clone() 或 arraycopy() 等),但没有一个适合我的问题(或者我只是愚蠢)。正如我所读到的,问题可能是“this”语句。如果有人能想出一些代码,我将非常感激,它可以在不更改原始对象的情况下复制我的对象!

非常感谢!

【问题讨论】:

    标签: java object copy


    【解决方案1】:

    这是如何对对象进行深层复制的情况,这就是 JAVA 序列化派上用场的地方。您可以使用对象序列化来保存对象的状态并在以后随时检索它。关注link了解更多详情。

    您需要做的是通过实现标记接口Serializable 将您的类标记为可序列化。

    class Board implements Serializable {
    .........
     ...........
      }
    

    编写一个关于如何保存和检索对象的额外方法。您可以从给定的链接获取代码。这将为您提供对象的精确副本,其中包含保存在数组中的值。您可以稍后根据需要对其进行修改。

    【讨论】:

    • 谢谢,这正是我想要的!今天学到了新东西。 :)
    • 感谢@LukasF。很高兴看到这样的回应。
    【解决方案2】:

    System.arraycopy(...) 应该可以工作,但它是为一维数组设计的,因此您需要在数组的第一个维度上进行迭代。 clone 也有同样的问题,它不会克隆底层对象(或数组)。

    以下可能会有所帮助:

    Board(Board Test){
        this.Field = new int[Test.Field.length][];
        for (int i = 0; i < Test.Field.length; i++) {
            this.Field[i] = new int[Test.Field[i].length];
            System.arraycopy(Test.Field[i], 0, this.Field[i], 0, Test.Field[i].length);
        }
    }
    

    如果纯粹的性能(还)不是问题,嵌套 2 个 for 循环可能会使代码更易于阅读,而不是使用 System.arraycopy(...)

    Board(Board Test){
        this.Field = new int[Test.Field.length][];
        for (int i = 0; i < Test.Field.length; i++) {
            this.Field[i] = new int[Test.Field[i].length];
            for (int j = 0; j < Test.Field[i].length; j++) {
                this.Field[i][j] = Test.Field[i][j];
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      您必须复制行和列。

      Board(int[][] field){
        Field=copyField(field);
      }
      
      Board(Board Test){
          Field = copyField(Test.Field);
      }
      
      private int[][] copyField(int[][] src) {
          if (ArrayUtils.isEmpty(src)) {
              throw new IllegalArgumentException("src is empty");
          }
          int[][] dest = new int[src.length][src[0].length];
          for (int i = 0; i < src.length; i++) {
              for (int j = 0; j < src[i].length; j++) {
                  dest[i][j] = src[i][j];
              }
          }
          return dest;
      }
      

      【讨论】:

        【解决方案4】:

        在构造函数Board(Board Test)中使用System.arraycopy(..)

        import java.util.Arrays;
        
        public class Board {
        
            int[][] Field;
        
            Board(int[][] field) {
                Field = field;
            }
        
            Board(Board Test) {
                this.Field = new int[Test.Field.length][];
                for (int i = 0; i < Test.Field.length; i++) {
                    this.Field[i] = new int[Test.Field[i].length];
                    System.arraycopy(Test.Field[i], 0, this.Field[i], 0, Test.Field[i].length);
                }
            }
        
            public void change(int x, int y, int number) {
                Field[y][x] = number;
            }
        
            public void Print() {
                System.out.println(Arrays.toString(Field[0]));
                System.out.println(Arrays.toString(Field[1]));
                System.out.println(Arrays.toString(Field[2]));
            }
        
            public static void main(String[] args) {
                int[][] testarray = {{0, 0, 0},
                {0, 0, 0},
                {0, 0, 0}};
        
                Board Test1 = new Board(testarray);
                Board Test2 = new Board(Test1);
        
                Test2.change(1, 1, 1);
                System.out.println("Test-1-----");
        
                Test1.Print();
        
                System.out.println("Test-2-----");
                Test2.Print();
            }
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-08-22
          • 2019-10-26
          • 1970-01-01
          • 2018-01-12
          • 1970-01-01
          • 2020-03-02
          • 1970-01-01
          • 2021-07-09
          相关资源
          最近更新 更多