• ベストアンサー

2次元配列のコピー

System.arraycopy(~) を使って二次元配列のコピーをしたいのですが、 出来るのでしょうか? 出来るのなら、使い方を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • sasadora
  • ベストアンサー率68% (59/86)
回答No.1

Javaの場合は2次元配列というものはないんです。 配列の中に配列があるという構造になっています。 なので、次のような配列オブジェクトは、 int[][] aryA = {{1, 2, 3}, {4, 5, 6, 7}}; 配列{1,2,3}と、配列{4,5,6,7}の2つを持った配列となります。 1個目の配列と2個目の配列の要素数が異なるので2次元ではないです。ややこしいですね。 2次元配列⇒表のような構造。Javaにはない 配列の配列⇒ツリーのような構造 aryA  ├aryA[0]  │ ├aryA[0][0]  │ ├aryA[0][1]  │ └aryA[0][2]  └aryA[1]    ├aryA[1][0]    ├aryA[1][1]    ├aryA[1][2]    └aryA[1][3] これをコピーする場合には2つの意味があります。 (1)外側の配列をコピー aryA = {配列, 配列}      ↓  ↓ aryB = {  ,  } これは、簡単でarraycopyを使うだけです。 int[][] aryB = new int[2][3]; System.arraycopy(aryA, 0, aryB, 0, 2); でもこの場合は、aryA[0][1]=100; とした時に、aryB[0][1]の値も変わってしまったようにみえます。 なぜなら、aryA[0]とaryB[0]は同じ配列オブジェクトを指しているからです。 (2)内側の配列をコピーする aryA = {{1, 2, 3}, {4, 5, 6, 7}}      ↓      ↓ aryC = {{1, 2, 4}, {4, 5, 6, 7}} これは、外側の配列を作ってから、内側の配列をarraycopyします。 //aryAの中の配列をコピーする例 int[][] aryC = new int[aryA.length][]; for (int i = 0; i < aryA.length; i++){   aryC[i] = new int[aryA[i].length];   System.arraycopy(aryA[i], 0, aryC[i], 0, aryA[i].length); } こうすると、aryA[0][1]=100; とaryA側の値を変えても、aryCには影響ありません。

W07A09
質問者

お礼

配列については、わかりました。 ありがとうございました。 ついでと言ってはなんですが、 例えば、クラスAyyayとmainと同じ値の配列を参照して Arrayでの値が変わったたら、mainでの配列も変わるように したいのですが、どのようにしたらよいでしょうか? まったく検討がつかなく悩んでいます。

その他の回答 (3)

  • sasadora
  • ベストアンサー率68% (59/86)
回答No.4

あくまでサンプルですが。 Shipは自身のXY座標や、自身を移動するメソッドを実装します。 mainで、すべてのShipを配列で管理し、全Shipを表示するメソッドなどを実装しました。 class Ship{  int point_x;  int point_y;    Ship(int x, int y){   this.point_x = x;   this.point_y = y;  }    void moveTo(int x, int y){   //自身のX,Y座標を変更する   this.point_x = x;   this.point_y = y;  } } public class Warship_Game {  public static void main(String[] args) {   //全てのShipを管理する配列   Ship[] ships = {    new Ship(1, 1),    new Ship(3, 2),   };      show(ships);   ships[0].moveTo(2, 1); //Ship[0]を移動する   show(ships);  }  static void show(Ship[] ships){   System.out.println("盤面");   for (int y = 0; y < 5; y++){    for (int x = 0; x < 5; x++){     Ship s = findShip(ships, x, y);     if (s == null){      System.out.print("□");     } else {      System.out.print("■");     }    }    System.out.println();   }  }  //座標X,YにあるShipを取得する  static Ship findShip(Ship[] ships, int x, int y){   for (int i = 0; i < ships.length; i++){    if (ships[i].point_x == x && ships[i].point_y == y){     return ships[i];    }   }   return null;  } }

W07A09
質問者

お礼

遅くなりましたがありがとうございました。 参考にさせていただきます。

  • sasadora
  • ベストアンサー率68% (59/86)
回答No.3

うーん、質問されたとおりの回答をするのであれば、配列オブジェクトをnewするのは、mainだけにして、Shipのコストラクタでnewするのをやめたらよいと思います。 つまり、mainでnewした配列dataを、コピーするのではなく、1つの配列オブジェクトを、mainとShipオブジェクトの2箇所で参照すれば、どちら側で変更しても、反映されてみえます。 でも、このWarship_Gameという名前から海戦ゲーム的なものを勝手に推測したうえで、アドバイスすると、 Shipクラスが、自身のx,y座標をもち、main側で複数のShipオブジェクト(駒?)を管理するような形にすれば、フィールド(盤面)の情報は要らないと思います。 サンプルが必要であれば、返信いただければ、書いてみようかと思います。

W07A09
質問者

お礼

何度もありがとうございます。 参考までに、サンプルをお願いしたいのですがよろしいでしょうか? 暇な時でいいのでお願いします。

  • sasadora
  • ベストアンサー率68% (59/86)
回答No.2

追加で聞かれた質問がよくわからないのですが、 こんな感じですか? class Array{  private int[][] aryA } class Main{  private int[][] aryB } aryAの値が変わったら、aryBの値も変わるというようにしたいと。 構造的には、常に同じ値を維持したいならば、2つ持っている意味はないので、aryA側だけで保持し続ければいいんじゃないでしょうか? つまりMain.aryBは削除して、Array.aryAに対するgetメソッドを用意して、それに対して変更を加えればよいと思います。 class Array{  private int[][] aryA  public int[][] getAryA(){ return aryA;} } class Main{ } もしくは、aryAとaryBが同じインスタンスを参照するようにするとか。 int [][] aryB = new int[2][3]; int [][] aryA = aryB; aryB[0][2] = 100; System.out.println(aryA[0][2]); 具体的な不都合がでるソースを見せてもらえれば、もっと正確に回答できると思います。

W07A09
質問者

補足

何度もすいません。 mainクラスではなく、mainとのやりとりです^^; 書き間違えました。 下記がプログラムになります。 class Ship{ int point_x; int point_y; int field_Data[][]; Ship(int[][] keep){ field_Data = new int [keep.length][]; System.arraycopy(keep,0,field_Data,0,5); } public void Direction(int point_x, int point_y){ //配列の値(field_Data)をかえます。 } static void show(int[][] data){ //配列の表示 } } public class Warship_Game{ public static void main(String[] args){ int data[][] = new int[5][5]; Ship.show(data); a.Direction(a.point_x,a.point_y); Ship.show(data); } 一回目のshowで表し、Directionで値を変え その変わった値を二回目のshowで表示するプログラムです。

関連するQ&A