这个主要就是想记录一个点,就是二维数组保存的元素就是一维数组的地址,这个概念大家都知道了,那么接下来就是我最近写程序发生的一个事情了。
这个程序我相信大家都是会写的,通过randomArr来随机打乱整个数组,之后通过printArr输出即可,那如果把调用循环来打乱数组,并且把打乱的数组储存在二维数组中又会发生什么情况呢。
import java.util.Random;
public class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
printArr(randomArr(arr));
}
//打乱整个数组
public static int[] randomArr(int[] arr) {
Random r = new Random();
for (int i = 0; i < arr.length; i++) {
//随机生成两个坐标
int pos1 = r.nextInt(arr.length);
int pos2 = r.nextInt(arr.length);
int tmp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = tmp;
}
return arr;
}
//输出整个数组
public static void printArr(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i != arr.length - 1) {
System.out.print(arr[i] + ",");
} else {
System.out.print(arr[i]);
}
}
System.out.println("]");
}
}
import java.util.Random;
public class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[][] res = new int[5][arr.length];
for (int i = 0; i < res.length; i++) {
//后面打乱依赖前面打乱生成的
res[i] = randomArr(arr);
printArr(randomArr(arr));
}
}
//打乱整个数组
public static int[] randomArr(int[] arr) {
Random r = new Random();
for (int i = 0; i < arr.length; i++) {
//随机生成两个坐标
int pos1 = r.nextInt(arr.length);
int pos2 = r.nextInt(arr.length);
int tmp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = tmp;
}
return arr;
}
//输出整个数组
public static void printArr(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i != arr.length - 1) {
System.out.print(arr[i] + ",");
} else {
System.out.print(arr[i]);
}
}
System.out.println("]");
}
}
程序运行结果如下:
[5,4,9,6,1,8,3,2,7]
[7,1,4,5,2,8,9,3,6]
[7,3,2,5,6,1,8,9,4]
[7,5,3,1,8,6,2,4,9]
[3,9,4,8,7,6,5,1,2]
理论上也确实是这个结果,但是此时res数组里面的元素呢?
import java.util.Random;
public class Test6 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[][] res = new int[5][arr.length];
for (int i = 0; i < res.length; i++) {
//后面打乱依赖前面打乱生成的
res[i] = randomArr(arr);
}
//打印res
for (int i = 0; i < res.length; i++) {
printArr(res[i]);
}
}
//打乱整个数组
public static int[] randomArr(int[] arr) {
Random r = new Random();
for (int i = 0; i < arr.length; i++) {
//随机生成两个坐标
int pos1 = r.nextInt(arr.length);
int pos2 = r.nextInt(arr.length);
int tmp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = tmp;
}
return arr;
}
//输出整个数组
public static void printArr(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i != arr.length - 1) {
System.out.print(arr[i] + ",");
} else {
System.out.print(arr[i]);
}
}
System.out.println("]");
}
}
程序运行结果如下:
[2,7,4,3,9,6,8,5,1]
[2,7,4,3,9,6,8,5,1]
[2,7,4,3,9,6,8,5,1]
[2,7,4,3,9,6,8,5,1]
[2,7,4,3,9,6,8,5,1]
此时会发现,二维数组的输出结果都是一样的,通过打印地址会发现,输出的地址都是一致的。
于是我们很快的可以想到,方法传递数组是传递的地址值,也就是最终我们在原数组中进行了修改,然后返回他,res数组里面的元素就都是arr,所以最终的值是一样的,那么我们又该如何解决呢?
可以对返回的数组重新给他开辟一片空间即可。(注意最后拷贝的时候不能是直接用数组名进行赋值,用数组名最终是将新创建的数组指向传进来的那个数组,我们需要的是拷贝每一个元素)
import java.util.Random;
public class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[][] res = new int[5][arr.length];
for (int i = 0; i < res.length; i++) {
//后面打乱依赖前面打乱生成的
res[i] = randomArr(arr);
}
//打印res
for (int i = 0; i < res.length; i++) {
printArr(res[i]);
}
}
//打乱整个数组
public static int[] randomArr(int[] arr) {
Random r = new Random();
int []res=new int[arr.length];
for (int i = 0; i < arr.length; i++) {
//随机生成两个坐标
int pos1 = r.nextInt(arr.length);
int pos2 = r.nextInt(arr.length);
int tmp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = tmp;
}
//拷贝元素,不能直接用res=arr;
for (int i = 0; i < arr.length; i++) {
res[i]=arr[i];
}
return res;
}
//输出整个数组
public static void printArr(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i != arr.length - 1) {
System.out.print(arr[i] + ",");
} else {
System.out.print(arr[i]);
}
}
System.out.println("]");
}
}