复制对象数组,然后修改原始对象而不影响副本 [英] copying an array of objects and then modifying the original without affecting the copy

查看:119
本文介绍了复制对象数组,然后修改原始对象而不影响副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我一直在努力解决这个看似微不足道的问题。我不一定知道要搜索什么。我一直在寻找解决方案。我需要制作2D数组的副本。该数组由对象组成(我创建的类称为Cell),但是一旦创建副本,我便将该副本存储到哈希映射中(以备后用),然后继续修改原始数组。问题是对原始文件的修改也会影响哈希图中现在的副本。基本上到一天结束时,我的哈希图将包含同一网格的许多版本。我尝试了传统的for循环复制方案array.clone(),System.arraycopy(...),Arrays.copyof()。...最后,我意识到我需要所谓的深层复制,您可以在其中进行复制每个对象的每个数据字段都被放入数组副本中的新对象。。。是的,这也不起作用。看看:

So I have been banging my head over this seemingly insignificant issue. I don't necessarily know what to search for. I have scoured around for solutions. I need to make a copy of 2D array. The array consists of objects (a class I created call Cell), but the as soon as I make a copy I store that copy into a hash map (for possible reference later), then continue to modify the original array. The issue is that the modifications to the original also affect the copy now in the hash map. Essentially at the end of the day, my hash map will consist of many versions of the same grid. I have tried array.clone(), System.arraycopy(...), Arrays.copyof(), the traditional for loop copying scheme.... Finally I realized that I need what was called a deep copy, where you copy each data field of each object into a new object into the array copy....yeah, that didn't work either. Take a look:

static Cell[][] gridCopy;
...
Cell[][] grid = getGrid(file); //get grid from a file (this is Sudoku if you must know)
...
static boolean SolveSudoku(Cell grid[][])
{
// If there is no unassigned location, we are done
    if (unassigned == null)
        return true; // success!

    int row = unassigned.row;
    int col = unassigned.col;
    ArrayList<Integer> domain = unassigned.domain;

    // consider digits 1 to 9
    for (int num = 0; num < domain.size(); num++)
    {
        //if looks promising
        if (isSafe(grid, row, col, domain.get(num)))
        {
            //gridCopy = new Cell[N][N];
            instance++;
            // make tentative assignment
            grid[row][col].value = domain.get(num);

            //here is my attempt at a deep copy
            for (int i = 0; i < N; i++)
                for (int j = 0; j < N; j++)
                    gridCopy[i][j] = new Cell(grid[i][j].row, grid[i][j].col, grid[i][j].value, grid[i][j].domain);
            states.put(instance, gridCopy); //save the current state in a map for reference if we backtrack

            //as soon as I change things here in the original, the copy in the 'states' map also changes
            updateSpecifiedDomains(grid, row, col, domain.get(num), true);

            printGrid(grid, "Instance" + String.valueOf(instance));

            // return, if success, yay!
            if (SolveSudoku(grid, choice))
                return true;

            // failure, un-assign & try again
            //int temp = grid[row][col].value;
            grid = states.get(instance); //retain previous state
            grid[row][col].value = UNASSIGNED;

            /*updateSpecifiedDomains(grid, row, col, temp, false);
            while (domain.contains(temp))
                grid[row][col].domain.remove((Integer)temp);*/

            //domain.remove((Integer)num);
        }
    }
    count++;
    instance--;
    return false; // this triggers backtracking
}


推荐答案

您正在创建对象的浅表副本。 Array.clone()仅适用于原始类型。您应该在要复制的对象的类中创建一个方法,该方法创建并返回具有相同属性值的类的新实例。然后,您可以遍历数组,获取每个对象的副本,然后将它们添加到新数组中,然后将新数组存储到哈希图中。

You are creating a shallow copy of your objects. Array.clone() will only work on primitive types. You should create a method in the Class of the objects you are trying to copy that creates and returns a new instance of the class with the same attribute values. Then you can loop through your array getting a copy of each object and add them to a new array then store the new array to your hashmap.

示例:

public class MyClass()
{
    private String temp;

    public MyClass(String temp)
    {
        this.temp = temp;
    }

    public MyClass copy()
    {
       MyClass copy = new MyClass(this.temp);
       //set attributes in constructor or using setters so they are the same as this object
       return copy;
    }
}

这篇关于复制对象数组,然后修改原始对象而不影响副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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