java--for循环each版本探索

当我们使用Java编程语言时,或许有创建多维数组并绑定其中的若干个子数组的需求。

总结:java的数组相对C++语言的数组在使用时有较大的优势,一方面是可以直接通过.length获取数组长度,并伴有数组越界检查;另一方面是,可以直接将一个数组赋值给另一个数组,尽管是通过引用(指针)模式。
比如在C++中

    int a[2][2] = {{1,2},{2,1}};
    int b[] = {1,1};
    a[0] = b;

被认为是非法的。
for(T a, T[])
for循环的foreach版本,实际上作用类似于将 T中的每一个元素作为值分别传给a。

比如我们想要绑定一个二维数组中 所有一维数组。
即改变 c[0][0]那么c[1][1]也会被绑定改变。你或许想要尝试使用foreach循环来修改。

class ArrayTester{
    public static void mainFunction(){
        int[] b = new int[]{1,2,3};
        int[][] c = new int[2][3];
        for(int[] i: c){
            i = b;
        }
        c[0][0] = 100;
        for(int[] p: c){
            for(int l: p){
                System.out.println(l);
            }
        }
    }
}
public class Q2 {
    public static void main(String[] args){
        ArrayTester.mainFunction();
    }
}

输出:0 0 0 100 0 0
很显然,并不起作用,我们尝试输出 数组指针

class ArrayTester{
    public static void mainFunction(){
        int[] b = new int[]{1,2,3};
        int[][] c = new int[2][3];
        System.out.println(b);
        for(int[] i: c){
            System.out.println("$"+i);
            i = b;
            System.out.println(i);
        }
        System.out.println("\n");
        c[0][0] = 100;
        for(int[] p: c){
            System.out.println(""+p);
            for(int l: p){
                System.out.println(l);
            }
        }
    }
}
public class Q2 {
    public static void main(String[] args){
        ArrayTester.mainFunction();
    }
}

输出:

[I@6f496d9f
$[I@1d81eb93
[I@6f496d9f
$[I@7291c18f
[I@6f496d9f


[I@1d81eb93
100
0
0
[I@7291c18f
0
0
0

发现循环内 i 指向的地址确实发生了改变。为什么不起作用呢?
较为完备的分析是:
对于一个foreach循环,对于原本二维数组的第一维数组的地址被直接赋值给了,循环 变量 i,但是 i 并不是代表原本数组的指针。
就像是

for(int k = 0; k < c.length;k++){
    int[] i = c[k];
    i = b;
}

i的改变并不会改变原来c数组中的 一维指针
于是我们尝试通过直接通过i对从c的引用,改变c中的元素。

class ArrayTester{
    public static void mainFunction(){
        int[] b = new int[]{1,2,3};
        int[][] c = new int[2][3];
        System.out.println(b);
        for(int[] i: c){
            System.arraycopy(b, 0, i, 0, i.length);
        }
        System.out.println("\n");
        c[0][0] = 100;
        for(int[] p: c){
            for(int l: p){
                System.out.println(l);
            }
        }
    }
}
public class Q2 {
    public static void main(String[] args){
        ArrayTester.mainFunction();
    }
}


输出:

100
2
3
1
2
3

这已经符合我们的代码编写预期。
但是如何才能关联元素呢?只需要修改一维数组指针,但不是通过foreach循环。

class ArrayTester{
    public static void mainFunction(){
        int[] b = new int[]{1,2,3};
        int[][] c = new int[2][3];
        System.out.println(b);
        for(int p = 0; p < 2; p++){
            c[p] = b;
        }
        System.out.println("\n");
        c[0][0] = 100;
        for(int[] p: c){
            for(int l: p){
                System.out.println(l);
            }
        }
    }
}
public class Q2 {
    public static void main(String[] args){
        ArrayTester.mainFunction();
    }
}


输出:

100
2
3
100
2
3

符合预期。

进而,通过c[0] = c[1]也可绑定从c[0]数组和c[1]数组

上一篇:aws lmanbda 硬件维护通知


下一篇:Fatmouse and cheese