プロが教える店舗&オフィスのセキュリティ対策術

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

A 回答 (4件)

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には影響ありません。
    • good
    • 0
この回答へのお礼

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

お礼日時:2005/12/05 02:29

あくまでサンプルですが。


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;
 }
}
    • good
    • 0
この回答へのお礼

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

お礼日時:2005/12/21 13:55

うーん、質問されたとおりの回答をするのであれば、配列オブジェクトをnewするのは、mainだけにして、Shipのコストラクタでnewするのをやめたらよいと思います。



つまり、mainでnewした配列dataを、コピーするのではなく、1つの配列オブジェクトを、mainとShipオブジェクトの2箇所で参照すれば、どちら側で変更しても、反映されてみえます。

でも、このWarship_Gameという名前から海戦ゲーム的なものを勝手に推測したうえで、アドバイスすると、

Shipクラスが、自身のx,y座標をもち、main側で複数のShipオブジェクト(駒?)を管理するような形にすれば、フィールド(盤面)の情報は要らないと思います。
サンプルが必要であれば、返信いただければ、書いてみようかと思います。
    • good
    • 0
この回答へのお礼

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

お礼日時:2005/12/07 00:46

追加で聞かれた質問がよくわからないのですが、


こんな感じですか?

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]);

具体的な不都合がでるソースを見せてもらえれば、もっと正確に回答できると思います。

この回答への補足

何度もすいません。
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で表示するプログラムです。

補足日時:2005/12/06 05:52
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!