配列とは?
ザックリ言うと、同じ種類の複数データを1つの変数に持つことができる仕組みです。
でも文字だけだとわかりずらいですよね?
なので以下のコードを確認してみて下さい。
1 2 3 4 5 6 7 |
// 変数でデータを持つ場合 int value1 = 1; int value2 = 2; int value3 = 3; // 配列で値を持つ場合 int[] values = new int[]{1, 2, 3}; |
通常だと1つの変数に1つの値を持たせますが、配列は1つの変数に同じ種類であれば複数の値を持たせることができます。
初期化
配列の初期化は基本的は2通りあります。
- 格納可能な要素数だけを決めて初期化する方法
- 値を決めて初期化する方法
格納可能な要素数だけを決めて初期化する
入れる値の数だけを決めて初期化する方法です。
初期化する値が決まっておらず、初期化する数だけが決まっている時に使用します。
1 |
String[] stringsFixedLength = new String[3]; |
値を決めて初期化する
初期化する値が決まっている時に使用します。
1 |
String[] stringsFixedValues = new String[]{"hoge", "fuga", "piyo"}; |
(注)配列数を決めない初期化はできない
1 |
String[] stringsNonFixedLength = new String[]; |
配列は初期化する要素数は決めておかないといけなので、上記のように数を指定しないとエラー: 配列の大きさが指定されていませんとなってしまいます。
要素数
配列の要素数はlengthフィールドを使います。
1 2 |
int[] sameValues = new int[]{1, 2, 3}; System.out.println("要素数 : " + sameValues.length); |
出力結果要素数 : 3
追加
配列を初期化した後、値を追加(配列の数を増やす)することはできません。
配列は初期化した時点の配列数を変えることができないからです。
ではどうするかというと、元の配列を複製しつつ、要素数を変えた新しい配列を作成するという方法を取ります。
それにはArrays.CopyOf()メソッドを使います。
例) 3つの配列に4つにしたい場合
1 2 3 4 |
int[] threeInts = new int[]{100, 200, 300}; int[] fourInts = Arrays.copyOf(threeInts, threeInts.length + 1); // 配列数を1つ増やす fourInts[3] = 400; // 増やした配列に値を代入する System.out.println(Arrays.toString(fourInts)); |
fourIntsの出力結果:[100, 200, 300, 400]
ソート
ソートはArrays.sort()メソッドを使用します。
Arrays.sort()メソッドは、int・String・doubleなどの各型に応じたメソッドが用意されており、大抵のものはソートすることができます。
ソートは自然順序で行われるので、数値は昇順、英字はアルファベット順になります。
1 2 3 4 |
int[] notSortedValues = new int[]{3, 1, 2}; System.out.println("before : " + Arrays.toString(notSortedValues)); Arrays.sort(notSortedValues); System.out.println("after : " + Arrays.toString(notSortedValues)); |
before : [3, 1, 2]
after : [1, 2, 3]
結合
複数の配列を1つの配列にまとめるには、System.arraycopy()メソッドを使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// 結合元の配列 int[] srcInts1 = new int[]{1, 2, 3}; int[] srcInts2 = new int[]{10, 20, 30}; // 結合先の配列 int[] destInts = new int[srcInts1.length + srcInts2.length]; System.out.println("before : " + Arrays.toString(destInts)); System.arraycopy(srcInts1, 0, destInts, 0, srcInts1.length); System.arraycopy(srcInts2, 0, destInts, srcInts1.length, srcInts2.length); System.out.println("after : " + Arrays.toString(destInts)); |
before : [0, 0, 0, 0, 0, 0]
after : [1, 2, 3, 10, 20, 30]
APIの仕様は以下のようになっています。
Object src, // 第1引数:結合元の配列
int srcPos, // 第2引数:結合元配列のコピー開始インデックス
Object dest, // 第3引数:結合先の配列
int destPos, // 第4引数:結合先配列のコピー開始インデックス
int length // 第5引数:結合元配列のコピー要素数)
ちょっと複雑なので図解します。
- 結合したい配列を準備します。(結合元の配列)
-
- 結合する配列を準備します。(結合先の配列)
結合元1と2の配列数が初期化する要素数になります。
- 結合する配列を準備します。(結合先の配列)
- 結合元の配列から結合先の配列へと値をコピーします。
結合元1のインデックス(0)から要素数分(3 : srcInts1.length)を、destIntsのインデックス(0)を開始位置としてコピーします。
次に、結合元2のインデックス(0)から要素数分(3 : srcInts2.length)を、destIntsのインデックス(3 : srcInts1.length)を開始位置としてコピーします。
検索
配列を検索する場合、Arrays.binarySearch()メソッドを使用します。
APIの仕様は以下の通りです。
int[] a, // 第1引数:検索対象の配列
int key // 第2引数:検索値
)戻り値: 値がある場合はインデックス(0以上)、ない場合は負数
このメソッドを使用する際の注意点は、事前にArrays.sort()をしておく必要がある点です。
また、同じ値が複数ある場合はどのインデックスが取得できるかは保証されていません。
あくまで検索値が存在するかを調べるために使うことになると思います。
1 2 3 |
int[] searchInts = new int[]{10, 30, 20}; Arrays.sort(searchInts); // 事前にソートしておく System.out.println("searched index : " + Arrays.binarySearch(searchInts, 30)); |
出力結果:searched index : 2
コピー
配列のコピーはcloneメソッドを使用します。
1 2 |
int[] srcInts = new int[]{1, 2, 3}; int[] copiedInts = srcInts.clone(); |
一次元配列であればこれでよいのですが、多次元配列になると参照コピーになり、コピー先の変更がコピー元への変更にもつながるので注意が必要です。
詳細な仕組みを確認したい方は、下記にて画像付きで解説しているので参照ください。
コピー: プリミティブ型の多次元配列
Listへの変換
Listへの変換にはArrays.asList()メソッドを使用します。
以下はintまたはIntegerの例です。
Listはオブジェクト型しか定義できないため、intの配列の場合はIntegerに変換する必要があります。
値から初期化
Arrays.asList()メソッドの引数に値を代入します。
1 |
List<Integer> integerList = Arrays.asList(1, 2, 3); |
Integer配列から初期化
Integer配列の場合、Arrays.asList()メソッドの引数に代入するだけでよいです。
1 2 |
Integer[] integers = new Integer[]{10, 20, 30}; integerList = Arrays.asList(integers); |
int配列をInteger配列に変換して初期化
int配列のままではListに変換できないため、Integer配列への変換を挟みます。
ちょっと難しいのでおまじないとして覚えておいて下さい。
やっていることとしては、Arrays.stream()メソッドでIntStreamが返され、更にboxed()メソッドを使うことでStream<Integer>になります。それをtoArray()メソッドでInteger型として生成するという過程を経ています。
1 2 3 |
int[] ints = new int[]{100, 200, 300}; Integer[] boxedInts = Arrays.stream(ints).boxed().toArray(Integer[]::new); integerList = Arrays.asList(boxedInts);; |
まとめ
- 配列とは同じ種類の値を複数格納する仕組みのこと。
- 初期化には値を決める初期化と、要素数を決める初期化がある。
- 要素数はlengthで取得できる。
- 値を追加するにはArrays.copyOf()メソッドを使う。
- ソートはArrays.sort()メソッドを使う。
- 結合するには、System.arraycopy()メソッドを使う。
- 検索にはArrays.binarySearch()メソッドを使う。
- コピーはclone()メソッドを使うが、多次元配列の場合は参照コピーになるので注意する。
- Listへの変換はArrays.asList()メソッドを使う。
最後に
配列についてはJava Silver SE 11試験でも出題されます。
ぜひしっかりと理解して合格を目指しましょう!
参考
【Java11】Arraysクラス
【Java11 】Systemクラス – arraycopyメソッド
コメント