我是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]);
}
}
我的意图如下:
我用以下代码尝试了这个:
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()等)并且它们都不适用于我的问题(或者我只是愚蠢)。正如我所读,问题可能是“这个”声明。如果有人想出一些代码可以复制我的对象而不改变原来的代码,我真的很感激!
非常感谢!
答案 0 :(得分:1)
System.arraycopy(...)
应该可以工作,但它是为1D数组设计的,因此您需要迭代数组的第一个维度。与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];
}
}
}
答案 1 :(得分:1)
这是如何对对象进行深层复制的情况,以及JAVA序列化方便的地方。您可以使用对象序列化来保存对象的状态,并在以后随时检索它。请点击link了解详情。
您需要做的是通过实施标记界面Serializable
将您的类标记为可序列化。
class Board implements Serializable {
.........
...........
}
编写一个关于如何保存和检索对象的额外方法。您可以从给定链接获取代码。这将为您提供对象的精确副本,其中包含保存在数组中的值。您可以稍后根据需要进行修改。
答案 2 :(得分:0)
您必须复制行和列。
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;
}
答案 3 :(得分:0)
在构造函数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();
}
}