Java | 配列の一部だけを取り出して新しい配列を作る

Java Java
スポンサーリンク

概要

Arrays.copyOfRange(original, from, to) は、元の配列の一部分を抜き出して新しい配列を作るメソッドです。
ポイントは インデックスのルール

  • from は「含む(inclusive)」開始インデックス。
  • to は「含まない(exclusive)」終了インデックス(つまり to-1 までが抜き出される)。
  • 新しい配列の長さは to - from

基本の使い方(整数配列の例)

import java.util.Arrays;

public class SliceExample {
    public static void main(String[] args) {
        int[] src = {12, 24, 18, 35, 21};

        // src[1] から src[3] まで(1,2,3)を抜き出す → 24,18,35
        int[] part = Arrays.copyOfRange(src, 1, 4);

        System.out.println(Arrays.toString(src));  // [12, 24, 18, 35, 21]
        System.out.println(Arrays.toString(part)); // [24, 18, 35]
    }
}
Java
  • from = 1to = 4 → 取り出す要素は src[1], src[2], src[3]
  • 新しい配列は元とは別物(コピーされる)。元配列を変えても新配列は影響を受けない(ただしオブジェクト配列は参照の“浅いコピー”)。

よくある間違い・注意点

  1. to は含まれないto の要素は結果に入らない)。
    例:from=0, to=3src[0], src[1], src[2] の3要素。
  2. 例外が出るケース
    • originalnullNullPointerException
    • from < 0 または from > original.lengthArrayIndexOutOfBoundsException
    • from > toIllegalArgumentException
  3. to が元配列の長さを超える場合はパディングされる
    • プリミティブ型(int など):超過分は 0 で埋まる。
    • 参照型(String など):超過分は null で埋まる。
      例:元配列長が 5、from=3, to=7 の場合、新配列長は 4(7-3)。src[3], src[4], 0, 0 のように残りはデフォルト値。
  4. オブジェクト配列の挙動
    • 配列の中身(オブジェクト自体)はコピーされず、参照がコピーされるだけ(浅いコピー)。つまり元の要素オブジェクトを変更すると新配列の要素にも影響することがあります。

例:to が配列長を超える例(挙動確認)

import java.util.Arrays;

public class PaddingExample {
    public static void main(String[] args) {
        int[] src = {1, 2, 3, 4, 5};
        int[] a = Arrays.copyOfRange(src, 3, 7); // from=3, to=7

        System.out.println(Arrays.toString(a)); // -> [4, 5, 0, 0]
    }
}
Java
  • a は長さ 7-3 = 4src[3]src[4] が入り、残りは 0 で埋まる。

参照型の例:

String[] s = {"A", "B", "C"};
String[] t = Arrays.copyOfRange(s, 1, 5);
// t -> ["B", "C", null, null]
Java

オブジェクト配列(参照の浅いコピー)例

import java.util.Arrays;

class Item {
    String name;
    Item(String n){ name = n; }
    public String toString(){ return name; }
}

public class ShallowCopy {
    public static void main(String[] args) {
        Item[] items = { new Item("apple"), new Item("banana"), new Item("cherry") };
        Item[] part = Arrays.copyOfRange(items, 0, 2); // apple, banana

        // 元のオブジェクトを書き換えると、コピー側も見た目は変わる
        items[0].name = "apricot";
        System.out.println(Arrays.toString(part)); // [apricot, banana]
    }
}
Java
  • part[0]items[0] は同じ Item オブジェクトを参照しているため、name の変更が両方に見える。

完全に同じ長さで配列全体をコピーしたいとき

配列全体をコピーする場合は:

int[] copy = Arrays.copyOfRange(src, 0, src.length);
// または
int[] copy2 = Arrays.copyOf(src, src.length);
Java

実践練習

問題1

int[] arr = {5, 10, 15, 20, 25} から 10, 15 を取り出すコードを書け(出力は [10, 15])。

答えのヒントfrom = 1, to = 3


問題2

String[] names = {"Tom","Hanako","Yuki","Sara"} から "Hanako","Yuki","Sara","null" のように長さ4の配列を作るにはどうする?(tofrom を指定して)

答えのヒントfrom=1, to=5 を使うと、元の長さを超えた分が null で埋まるので結果は ["Hanako","Yuki","Sara",null]


問題3(注意問題)

次は何が起きる?
Arrays.copyOfRange(arr, 4, 2);
→ どうなるか説明せよ。

答えfrom > to なので IllegalArgumentException が投げられます。


トラブルシューティング(実際に困りやすいポイント)

  • 「配列の終端の要素が入らない!」 → tolength にするのを忘れている可能性あり(to は含まれない)。
  • 「例外が出た」 → fromto の値を確認(負の値や from>lengthfrom>to になっていないか)。
  • 「オブジェクトの中身だけ変わった」 → オブジェクト配列は浅いコピー。元のオブジェクトを変更するとコピー側も変わる。

まとめ(初心者が覚えるべき最重要ポイント)

  1. from は含む、to は含まない(to-1 まで)。
  2. 新しい配列の長さは to - from
  3. from < 0 / from > length / from > to は例外。
  4. to が長さを超えるとデフォルト値で埋められる(int→0、参照型→null)。
  5. オブジェクト配列は参照の浅いコピー
Java
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました