Java | 配列のコピー応用編

Java Java
スポンサーリンク

ここまで「コピーの基本」と「浅い/深いコピー」を理解したので、さらに一歩進んだ 応用編 を紹介します。実際のプログラムで遭遇する「コピーの落とし穴」や「便利な使い方」を題材にしますね。


コピーの基本の応用編

1. 配列の結合(マージ)

  • 状況: 2つの配列をまとめて1つにしたい。
  • 例:
int[] a = {1, 2, 3};
int[] b = {4, 5, 6};
int[] merged = new int[a.length + b.length];

System.arraycopy(a, 0, merged, 0, a.length);
System.arraycopy(b, 0, merged, a.length, b.length);

System.out.println(Arrays.toString(merged)); // [1, 2, 3, 4, 5, 6]
Java

👉 コピーを使えば「配列の結合」が簡単にできる。


2. コピーしてバックアップを作る

  • 状況: 元の配列を残しておきたいとき。
  • 例:
int[] data = {10, 20, 30};
int[] backup = Arrays.copyOf(data, data.length);

data[0] = 999;

System.out.println(Arrays.toString(data));   // [999, 20, 30]
System.out.println(Arrays.toString(backup)); // [10, 20, 30]
Java

👉 コピーを「スナップショット」として使うと、変更前の状態を保持できる。


3. 多次元配列のコピー

  • 状況: 2次元配列をコピーしたいとき。
  • 例:
int[][] matrix = {{1, 2}, {3, 4}};
int[][] copy = new int[matrix.length][];

for (int i = 0; i < matrix.length; i++) {
    copy[i] = Arrays.copyOf(matrix[i], matrix[i].length);
}

copy[0][0] = 99;

System.out.println(Arrays.deepToString(matrix)); // [[1, 2], [3, 4]]
System.out.println(Arrays.deepToString(copy));   // [[99, 2], [3, 4]]
Java

👉 外側だけコピーすると「内側の配列」が共有されてしまうので、ループで内側もコピーする必要がある。


浅い/深いコピーの応用編

1. 複合オブジェクトのコピー

  • 状況: Student クラスが namescores(配列)を持つ場合。
  • 浅いコピー: scores が共有される。
  • 深いコピー: scores も新しくコピーする。
class Student {
    String name;
    int[] scores;
    Student(String name, int[] scores) {
        this.name = name;
        this.scores = scores;
    }
}

Student[] src = {
    new Student("Alice", new int[]{90, 80}),
    new Student("Bob", new int[]{70, 60})
};

// 深いコピー
Student[] deep = new Student[src.length];
for (int i = 0; i < src.length; i++) {
    deep[i] = new Student(src[i].name, Arrays.copyOf(src[i].scores, src[i].scores.length));
}

deep[0].scores[0] = 100;

System.out.println(Arrays.toString(src[0].scores)); // [90, 80]
System.out.println(Arrays.toString(deep[0].scores)); // [100, 80]
Java

👉 「浅いコピー」だと scores が共有されてしまう。「深いコピー」なら完全に独立。


2. コピーを使った Undo 機能

  • 状況: ゲームやエディタで「元に戻す」機能を作りたい。
  • 方法: 配列の状態をコピーして履歴として保存しておく。
int[] state = {1, 2, 3};
List<int[]> history = new ArrayList<>();

// 状態を保存
history.add(Arrays.copyOf(state, state.length));

state[0] = 99; // 変更

// Undo(履歴から復元)
state = Arrays.copyOf(history.get(0), state.length);

System.out.println(Arrays.toString(state)); // [1, 2, 3]
Java

👉 コピーを「履歴」として使うことで、Undo機能が作れる。


✅ まとめ

  • コピーの基本応用: 結合・バックアップ・多次元配列コピー
  • 浅い/深いコピー応用: 複合オブジェクトの安全なコピー、Undo機能の実装
  • ポイント: 「浅いコピーは参照を共有」「深いコピーは中身も新しく作る」

💡 提案: さらに実践的にするなら「ゲームのキャラクター配列」「図書館の本リスト」などを題材にしてコピーを使うと面白いです。

タイトルとURLをコピーしました