如何在不更改原始对象的情况下复制对象 - java
how to copy an object without changing the orignial - java
我是 java 的初学者。在为一个小项目编写代码时,我偶然发现了一个问题,经过多次尝试后我仍然无法解决。
我有一个小的 class,它只存储一个二维数组:
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]);
}
}
我的意图如下:
- 使用 testarray 创建对象 Test1。
- 创建一个对象 Test2,该对象具有 Test1 的 testarray 的独立副本。
- 在 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 的数组的方式完全相同!我已经在这个论坛上搜索过,发现了很多类似的 post。关于如何解决这个问题也有多种想法,但我尝试了很多(如使用方法 clone() 或 arraycopy() 等),其中 none 对我的问题有效(或者我只是愚蠢).正如我所读,问题可能出在 "this" 语句上。如果有人能想出一些代码,可以在不更改原始对象的情况下复制我的对象,我将非常感激!
非常感谢!
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);
}
}
如果纯 perf(还)不是问题,嵌套 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];
}
}
}
您必须复制行和列。
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;
}
在构造函数中使用 System.arraycopy(..)
Board(Board Test)
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();
}
}
这就是如何对对象进行深度复制的情况,这就是 JAVA 序列化派上用场的地方。您可以使用对象序列化来保存对象的状态并在以后的任何时间点检索它。关注link了解更多详情。
您需要做的是通过实现标记接口 Serializable
.
将 class 标记为可序列化
class Board implements Serializable {
.........
...........
}
编写一个关于如何保存和检索对象的额外方法。您可以从给定的 link 中获取代码。这将为您提供对象的精确副本,并将值保存在数组中。您可以稍后根据需要对其进行修改。
我是 java 的初学者。在为一个小项目编写代码时,我偶然发现了一个问题,经过多次尝试后我仍然无法解决。 我有一个小的 class,它只存储一个二维数组:
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]);
}
}
我的意图如下:
- 使用 testarray 创建对象 Test1。
- 创建一个对象 Test2,该对象具有 Test1 的 testarray 的独立副本。
- 在 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 的数组的方式完全相同!我已经在这个论坛上搜索过,发现了很多类似的 post。关于如何解决这个问题也有多种想法,但我尝试了很多(如使用方法 clone() 或 arraycopy() 等),其中 none 对我的问题有效(或者我只是愚蠢).正如我所读,问题可能出在 "this" 语句上。如果有人能想出一些代码,可以在不更改原始对象的情况下复制我的对象,我将非常感激!
非常感谢!
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);
}
}
如果纯 perf(还)不是问题,嵌套 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];
}
}
}
您必须复制行和列。
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;
}
在构造函数中使用 System.arraycopy(..)
Board(Board Test)
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();
}
}
这就是如何对对象进行深度复制的情况,这就是 JAVA 序列化派上用场的地方。您可以使用对象序列化来保存对象的状态并在以后的任何时间点检索它。关注link了解更多详情。
您需要做的是通过实现标记接口 Serializable
.
class Board implements Serializable {
.........
...........
}
编写一个关于如何保存和检索对象的额外方法。您可以从给定的 link 中获取代码。这将为您提供对象的精确副本,并将值保存在数组中。您可以稍后根据需要对其进行修改。