Java で 2 次元配列をコピーする

Waleed 2023年10月12日
  1. Java で 2 次元配列をコピーするループ反復法
  2. Java で clone() メソッドを使って 2 次元配列をコピーする
  3. Java で arraycopy() メソッドを使って 2 次元配列をコピーする
Java で 2 次元配列をコピーする

2 次元配列の要素を別の配列にコピーしようとするときはいつでも、元の配列を宛先配列に割り当てることがよくあります。このアプローチが論理的に間違っている理由を最初に説明します。

下記の解決策は論理的に間違っていますが、この解決策が機能しない理由をお知らせします。

// Java Program to copy 2-dimensional array
// create 2D array
int[][] arr1 = {{2, 4, 6}, {8, 10, 12}};
// creating the same array with the same size
int[][] arr2 = new int[arr1.length];
// this code does not copy elements of arr1[ ] to arr2[ ] because arr2[ ] sill refer to the same
// location
arr2 = arr1;

arr2=arr1 と書くとき、arr2[ ]arr1[ ] への参照を割り当てます。したがって、1つの配列を変更すると、コピーされた配列と元の配列の両方に反映されます。これは、両方の配列が同じ場所を指しているためです。

この事実を実証するために、以下に示すコードを見てください。

// A Java program to demonstrate assigning an array reference doesn't make any sense

public class copy2DArray {
  public static void main(String[] args) {
    // Create an array arr1[]
    int[][] arr1 = {{2, 4, 5}, {6, 8, 10}};
    // Create an array arr2[] with the same size
    int[][] arr2 = new int[arr1.length][];
    // Doesn't copy elements of arr1 to arr2, but only arr2 starts refering arr1
    arr2 = arr1;
    // Any changing in the arr2 also reflects in the arr1 because
    // both are referin to the same location
    arr2[0][0] = 88;
    System.out.println("Elements of arr1[] are:");
    for (int i = 0; i < arr1.length; i++) {
      for (int j = 0; j < arr1.length; j++) {
        System.out.println(arr1[i][j] + " ");
      }
    }
    System.out.println("\n\nElements of arr2[] are:");
    for (int i = 0; i < arr2.length; i++) {
      for (int j = 0; j < arr2.length; j++) {
        System.out.println(arr2[i][j] + " ");
      }
    }
  }
}

出力:

Elements of arr1[] are:
88
4
6
8
Elements of arr2[] are:
88
4
6
8

上記の例では、開発者が 2 次元配列の要素をコピーするときによくある間違いについて説明しました。次に、同じタスクを実行するための正しい方法について説明します。

Java では、次の方法を使用して配列要素をコピーできます。

  1. 配列のすべての要素を繰り返し、各要素をコピーします。
  2. clone() メソッドを使用します。
  3. arraycopy() メソッドを使用します。

Java で 2 次元配列をコピーするループ反復法

2 次元配列をコピーするためのループ反復手法。この方法を使用すると、宛先または元の配列の変更が元の配列に影響を与えないことがわかります。したがって、元のアレイはそのまま残ります。

// A Java program to demonstrate assigning an array reference doesn't make any sense
import java.util.Arrays;
public class copy2DArray {
  public static void main(String[] args) {
    // Create an array arr1[ ]
    int[][] arr1 = {{2, 4, 5}, {6, 8, 10}};
    // Create an array arr2[ ] with the same size
    int[][] arr2 = new int[arr1.length][];
    // Copying elements of arr1[ ] to arr2[ ]
    for (int i = 0; i < arr1.length; i++) {
      // allocation space to each row of arr2[]
      arr2[i] = new int[arr1[i].length];
      for (int j = 0; j < arr1[i].length; j++) {
        arr2[i][j] = arr1[i][j];
      }
    }

    // Any change in the elements of arr2[ ] will not be reflected  in an original array
    arr2[0][0] = 90;
    System.out.println("Elements of arr1[] are:");
    for (int i = 0; i < arr1.length; i++) {
      for (int j = 0; j < arr1[0].length; j++) {
        System.out.println(arr1[i][j] + " ");
      }
    }
    System.out.println("\n\nElements of arr2[] are:");
    for (int i = 0; i < arr2.length; i++) {
      for (int j = 0; j < arr2[0].length; j++) {
        System.out.println(arr2[i][j] + " ");
      }
    }
  }
}

出力:

Elements of arr1[] are:
2 
4
5 
6 
8
10 
Elements of arr2[] are:
90 
4 
5 
6 
8 
10

Java で clone() メソッドを使って 2 次元配列をコピーする

前の方法では、ループ反復手法を使用して 2 次元配列要素をコピーしました。clone() メソッドでも同じタスクを実行できます。

// A Java program to demonstrate assigning an array reference doesn't make any sense

import java.util.Arrays;
public class copy2DArray {
  public static void main(String[] args) {
    // Create an array arr1[]
    int[][] arr1 = {{2, 4, 5}, {6, 8, 10}};
    // Create an array arr2[] with the same size
    int[][] arr2 = new int[arr1.length][];
    // Copying elements of arr1[ ] to arr2[ ] using the clone() method
    for (int i = 0; i < arr1.length; i++) arr2[i] = arr1[i].clone();
    // Any change in the elements of arr2[] will not be reflected in an original array
    arr2[0][0] = 90;
    System.out.println("Elements of arr1[] are:");
    for (int i = 0; i < arr1.length; i++) {
      for (int j = 0; j < arr1[0].length; j++) {
        System.out.println(arr1[i][j] + " ");
      }
    }
    System.out.println("\n\nElements of arr2[] are:");
    for (int i = 0; i < arr2.length; i++) {
      for (int j = 0; j < arr2[0].length; j++) {
        System.out.println(arr2[i][j] + " ");
      }
    }
  }
}

出力:

Elements of arr1[] are:
2 
4
5 
6 
8
10 
Elements of arr2[] are:
90 
4 
5 
6 
8 
10

Java で arraycopy() メソッドを使って 2 次元配列をコピーする

同様に、arraycopy() メソッドを使用して 2 次元配列をコピーできます。このメソッドを使用してすべての配列要素を反復することなく、任意の 2 次元配列の要素をコピーできます。このメソッドを使用するには、次のパラメーターを指定する必要があります。

  • src:コピーする必要のあるソース配列
  • srcPos:元の配列の開始位置。
  • dest:宛先配列。
  • destPos:宛先配列の開始インデックス。
  • length:コピーする 2 次元配列の要素の総数

例外:

  • NullPointerException:ソース配列または宛先配列のいずれかが定義されていないか、存在しない場合。
  • ArrayStoreException:開発者が整数配列タイプを文字列配列にコピーしようとすると、この状況でこの例外が自動的にトリガーされます。

例:

package sampleProject;
import java.util.Arrays;
public class Codesample {
  public static void main(String[] args) {
    // Create an array arr1[]
    int[][] arr1 = {{2, 4, 5}, {6, 8, 10}};
    // Create an array arr2[] with the same size
    int[][] arr2 = new int[arr1.length][];
    // Copying elements of arr1[] to arr2[] using the clone() method
    for (int i = 0; i < arr1.length; i++) {
      arr2[i] = new int[arr1[i].length];
      System.arraycopy(arr1[i], 0, arr2[i], 0, arr1[i].length);
    }
    // Any change in the elements of arr2[] will not be reflected in an original array
    arr2[0][0] = 90;
    System.out.println("Elements of arr1[] are:");
    for (int i = 0; i < arr1.length; i++) {
      for (int j = 0; j < arr1[0].length; j++) {
        System.out.println(arr1[i][j] + " ");
      }
    }
    System.out.println("\n\nElements of arr2[] are:");
    for (int i = 0; i < arr2.length; i++) {
      for (int j = 0; j < arr2[0].length; j++) {
        System.out.println(arr2[i][j] + " ");
      }
    }
  }
}

出力:

Elements of arr1[] are:
2 
4
5 
6 
8
10 
Elements of arr2[] are:
90 
4 
5 
6 
8 
10

関連記事 - Java Array