配列要素アクセスの全体像
配列の要素アクセスは「添字(インデックス)で特定の位置の値を読み書きする」操作です。Java の配列は 0 始まりで、最後の要素の添字は length - 1。arr[i] の形でアクセスし、読み取りも代入も同じ表記を使います。重要なのは「添字の範囲を必ず守る」「型を一致させる」「長さは固定」という3点です。
基本の読み書き
読み取り(get)と代入(set)
int[] a = {10, 20, 30};
int x = a[0]; // 読み取り:先頭を取得(10)
a[1] = 99; // 代入:2番目を更新(20→99)
System.out.println(a[2]); // 30
Java[] の中は整数添字です。存在しない位置を指定すると ArrayIndexOutOfBoundsException が発生します。配列の型と要素の型は一致している必要があります(int[] に文字列は入れられない)。
重要ポイントの深掘り:範囲と境界(オフバイワン対策)
0 始まりと最後の位置
String[] words = {"Java", "is", "fun"};
System.out.println(words[0]); // 先頭("Java")
System.out.println(words[words.length-1]); // 最後("fun")
Java配列は 0 始まりです。終了条件は「未満(i < arr.length)」を徹底すると、最後を踏み越えるミスを防げます。<= を使うと最後の次を触って例外が起きがちです。
範囲外アクセスの例と回避
int[] a = {10, 20, 30};
// a[3] = 0; // 例外:範囲外(有効な添字は 0〜2)
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]); // 未満条件で安全
}
Java「空配列(長さ0)」「要素1件」「最大長」の3パターンでテストする習慣をつけると、境界バグが激減します。
重要ポイントの深掘り:添字計算と安全設計
位置を使ったロジック(先頭・末尾・中央)
int[] arr = {10, 20, 30, 40, 50};
int first = arr[0];
int last = arr[arr.length - 1];
int mid = arr[arr.length / 2]; // 中央(偶数長は「右寄り」)
Java「先頭」「末尾」「中央」をコードで表現する時は、length を使った式で書くと配列サイズが変わっても安全です。マジックナンバー(固定の添字)は避けましょう。
オフセットとステップ
int[] a = {0,1,2,3,4,5,6};
for (int i = 0; i < a.length; i += 2) {
System.out.println(a[i]); // 0,2,4,6(2ステップ)
}
Java一定ステップで走査する場合も「未満条件」を守れば安全です。負の添字や範囲外に飛ぶ計算は避け、式の結果が常に 0 <= i < length を満たすように設計します。
重要ポイントの深掘り:参照型と null の扱い
参照型要素の初期値は null
String[] names = new String[3]; // {null, null, null}
if (names[0] == null) {
names[0] = "sato"; // 有効値をセットしてから使う
}
System.out.println(names[0].toUpperCase()); // "SATO"
Java参照型(String, Object など)の配列は、生成直後は null が入っています。メソッド呼び出し前に「null でない」ことを確認するか、最初に安全な既定値で埋める設計にします。
プリミティブ配列との違い
int[] p = new int[3]; // {0,0,0}(プリミティブは 0 始まり)
Integer[] w = new Integer[3]; // {null,null,null}(ラッパーは参照型)
Javaプリミティブ配列は null にはなりませんが、ラッパー配列は null を持ちます。API がどちらを要求しているか確認しましょう。
多次元配列の要素アクセス(配列の配列)
行×列のアクセス
int[][] m = {
{1, 2, 3},
{4, 5, 6}
};
System.out.println(m[1][2]); // 6(2行目・3列目)
Java「外側の添字が行、内側が列」と考えると分かりやすいです。ジャグ配列(行ごとに列数が違う)では各行の length を必ず参照します。
int[][] jag = { {1}, {2,3}, {4,5,6} };
for (int r = 0; r < jag.length; r++) {
for (int c = 0; c < jag[r].length; c++) {
System.out.printf("[%d,%d]=%d%n", r, c, jag[r][c]);
}
}
Java実用例で身につける
例 1: 位置に応じた処理(区切りなしで最後を出力)
public class PrintWithComma {
public static void main(String[] args) {
int[] a = {10, 20, 30, 40};
for (int i = 0; i < a.length; i++) {
boolean last = (i == a.length - 1);
System.out.print(a[i]);
if (!last) System.out.print(", "); // 最後だけ区切りを出さない
}
}
}
Java例 2: 値の入れ替え(スワップ)
public class Swap {
public static void main(String[] args) {
int[] a = {10, 20, 30};
int i = 0, j = 2;
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
System.out.println(java.util.Arrays.toString(a)); // [30, 20, 10]
}
}
Java例 3: 範囲チェックで安全にアクセス
public class SafeAccess {
public static void main(String[] args) {
String[] words = {"Java", "is", "fun"};
int idx = 3; // 本来はユーザー入力などの外部値
if (0 <= idx && idx < words.length) {
System.out.println(words[idx]);
} else {
System.out.println("範囲外");
}
}
}
Java仕上げのアドバイス(重要部分のまとめ)
- 添字は 0 始まり。最後は
length - 1。走査の条件は「未満(i < length)」でオフバイワンを防ぐ。 - 参照型配列は初期値が
null。使う前に null を排除するか、最初に安全な値で埋める。 - 要素の型は配列の型と一致が必要。プリミティブ配列とラッパー配列を混同しない。
- 多次元は「配列の配列」。各行の
lengthを使って安全にアクセスする。 - 外部入力で添字が決まる場合は、必ず範囲チェックを入れて例外を防ぐ。
