leetCode の「Game of Life」を解いているときに、ちょっとハマったので、メモしておく。
https://leetcode.com/problems/game-of-life/
いつも Javaのintの配列を複製する時は、以下のようにしている。
int[] orgArrya1 = {1,2,3}; int[] clonedArrya1 = orgArrya1.clone();
int はプリミティブ型(参照型ではない)ので、これでディープコピーになっている。実際に、以下のようにコピー元の配列をいじっても、コピー先の配列には影響しない。
orgArrya1[0] = 0; System.out.println(clonedArrya1[0]); // 1
これと同じ感じでintの2次元配列を扱ってはいけない。というのも、2次元配列では、以下のようにコピー元の変更がコピー先に影響する。
int[][] orgArray2 = {{1,2,3}, {4,5,6}}; int[][] clonedArray2 = orgArray2.clone(); orgArray2[0][0] = 0; System.out.println(clonedArray2[0][0]); // 0
これは2次元配列の成り立ちを考えれば、自然なことである。Javaでは2次元配列では、配列の中に配列を含んでいる。そして、配列は参照型なので、clone でコピーしてもそれは参照のコピーとなり、ディープコピーにはならない。実際に、上記のコピー元(orgArray2)とコピー先(clonedArray2)の配列のアドレスを出力してみると、これが分かる。
System.out.println(orgArray2); // [[I@1540e19d System.out.println(clonedArray2); // [[I@677327b6 System.out.println(orgArray2[0]); // [I@14ae5a5 System.out.println(clonedArray2[0]); // [I@14ae5a5 System.out.println(orgArray2[1]); // [I@7f31245a System.out.println(clonedArray2[1]); // [I@7f31245a
ということで、Javaでintの2次元配列を複製するには、素直に2重ループを回した方が良さそうだ。