【発展】多次元配列を理解する
Javaの多次元配列は「配列を要素として持つ配列」です。表のように使えますが、行ごとの長さが異なったり、まだ行が作られていなかったりします。一次元の添字とlengthから始め、参照の共有と二重ループまで図で結び付けます。
この単元で学ぶこと
- 配列の宣言・生成・初期値を区別できる
- 多次元配列の外側と内側のlengthを判断できる
- 参照共有・null・範囲外をコードから識別できる
本文解説
一次元配列を復習する int[] scores=new int[3];はint要素を三つ持つ配列を生成します。添字は0、1、2で、scores.lengthは3です。生成した配列自身の長さは後から変わりません。scores[3]は四番目なので範囲外です。lengthはフィールドでありlength()と呼び出しません。
宣言と生成は別 int[] scores;は配列を参照する変数の宣言だけです。ローカル変数なら読む前に代入が必要です。new int[3]で配列を生成したとき、各要素には0が入ります。new boolean[2]ならfalse、new String[2]なら各要素はnullです。配列変数がnullである状態と、存在する配列の要素がnullである状態を区別します。
値を並べて初期化する int[] scores={70,80,90};は三要素の配列を作ります。宣言とは別の代入ならscores=new int[]{70,80,90};と書けますが、scores={70,80,90};とは書けません。new int[3]{70,80,90}のように次元の大きさと初期化子を同時に指定する構文も不正です。
配列の配列 int[][] table=new int[2][3];は外側に二つの要素があり、各要素が長さ3のint配列を参照します。table.lengthは2、table[0].lengthは3、table[1][2]は初期値0です。table[行][列]とたどり、最初に外側の添字を評価します。
行ごとに長さを変える int[][] table={{1,2},{3}};では外側の長さは2ですが、table[0].lengthは2、table[1].lengthは1です。常に長方形とは限りません。全要素を処理するなら、各行のtable[i].lengthを使います。外側のlengthを列数として使うと短い行で範囲外になります。
外側だけ生成する int[][] table=new int[2][];は外側だけを生成し、table[0]とtable[1]はnullです。table[0]=new int[3];を行うと最初の行だけが使えます。まだnullのtable[1].lengthを読むとNullPointerExceptionです。存在する行で添字が長さ以上ならArrayIndexOutOfBoundsExceptionとなり、原因は違います。
参照の代入 int[] a={1,2}; int[] b=a;は配列の複製ではなく、同じ配列への参照をコピーします。b[0]=9;の後にa[0]を読むと9です。一方b=new int[]{7};はbの参照先を別配列へ変えるだけで、aが元の配列を参照することは変わりません。
cloneと二次元の注意 int[] b=a.clone();なら一次元int配列の要素を別配列へコピーするため、bの要素変更はaへ反映しません。int[][] copied=table.clone();では外側だけを複製し、内側の配列の参照は共有します。copied[0][0]の変更は元の同じ行にも見えます。各行も独立させるには行ごとの複製を設計します。
ループと確認 int[][] table={{1,2},{3}}; int sum=0; for(int i=0;i<table.length;i++){ for(int j=0;j<table[i].length;j++){ sum+=table[i][j]; } } System.out.println(sum);は6です。ここでは全ての行が生成済みという前提です。new int[2][]のような例では、行を生成するかnullを判定してから内側のlengthを使います。
図解
重要ポイント
- 配列の長さと最後の有効添字は一つ違う。
- 二次元配列は配列への参照を並べた配列。
- 行の長さは行ごとに調べる。
- 参照の代入と要素の複製は異なる。
間違えやすい点
- new int[2][]で内側も生成済みと思わない。
- 二次元配列が常に長方形だと思わない。
- 二次元のcloneで全ての行も独立すると思わない。
用語解説
- 添字
- 配列要素を選ぶ0始まりの整数位置。
- length
- 生成済み配列の要素数を表すフィールド。
- 参照
- 配列などのオブジェクトを指す値。
- ジャグ配列
- 行ごとの長さが異なる配列の配列。
- 浅いコピー
- 外側の要素をコピーしても参照先の内部オブジェクトは共有されるコピー。
関連教材
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
確認問題の出題・採点や学習履歴の保存にはログインが必要です。