
この記事の要点
- ArrayListは配列に似ているが、後から要素を追加できる点が異なる
- 必要な要素数が予測できる場合は配列を使い、プログラムを実行するまで要素数がわからない場合はArrayListを使う
- List.of()メソッドやArrays.asList()メソッドを使うと、初期化が簡単になる
以前、Javaの特徴や案件別の必要スキルなど、Javaの基礎について解説していました。
JavaのArrayListは配列に近い性質を持っていますが、必要に応じて要素を追加できる点が便利です。
しかし配列と違ってやや扱いが難しく、用意されているメソッドも多いため理解するのは大変です。
そこで当記事ではArrayListの基本的な使い方に加えて、よく使われるメソッドだけを厳選して紹介しています。
さらに応用テクニックとして、2次元リストの扱い方についても紹介しています。
ArrayListをよく使う方、そしてこれから身につけたい方におすすめの内容です。
ArrayListとは
ArrayListはList(リスト)の一種で、使い方は配列に似ています。
ただし、後から要素数を増やせる点が配列との最大の違いです。
配列の場合、作成時にサイズを確定させます。
そのサイズ以上のインデックスの要素を読み書きしようとすると、ArrayIndexOutOfBoundsExceptionという例外が発生します。
int[] array = new int[2]; array[0] = 0; array[1] = 1; array[2] = 2; // ArrayIndexOutOfBoundsException
一方、ArrayListの場合は、メモリなどの上限の範囲で後から要素を追加できます。
その代わり、配列よりもメモリ消費量が大きくなります。
どれくらいの要素数が必要か予めわかる場合は配列を使う、プログラムを実行するまで要素数がわからない場合はArrayListを使う、というように使い分けるとよいでしょう。
ただし、これは使い分けの目安です。要素数がわかっていても、追加・削除やListを使う処理との連携が必要な場合はArrayListを使います。
例えば、顧客の現場でAIやシステムを実装するFDEが、既存のJavaシステムから取得したデータをAIへ渡す場合にも、一覧を扱うための基礎として役立ちます。
ArrayListの基本的な書き方
ArrayListの使い方は、以下の通りです。
import java.util.*; ArrayList<要素の型> list = new ArrayList<>();
ArrayListは「java.util」パッケージで提供されているので、importが必要です。
「<要素の型>」の部分はジェネリクスといい、やや難しい仕組みなので、慣れるまでは書き方を暗記して使うようにしましょう。
具体例を紹介します。
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
for(int i = 0;i < list.size();i++){
String str = list.get(i);
System.out.println(str);
}
使われているメソッドの詳細については後述しますが、addメソッドでリストに追加、getメソッドで引数に指定したインデックスの値を取得しています。
ほぼ配列と同じような使い方ができているのがお分かりいただけると思います。
ArrayListの主要メソッド
ArrayListでは、次のようなメソッドがよく使われます。
| 戻り値 | メソッド | 説明 |
|---|---|---|
| boolean | add(E e) | リストの最後に要素を追加する。 |
| void | add(int index, E element) | 第一引数で指定した位置に、要素を追加する。 |
| boolean | contains(Object o) | 引数のオブジェクトがリスト内にあるか判定する(あればtrue、なければfalse)。 |
| E | get(int index) | 引数で指定した位置の要素を取得する。 |
| E | remove(int index) | 引数で指定した位置の要素を削除し、削除した要素を返す。 |
| int | size() | リスト内の要素の数を取得する。 |
※表中の「E」は、リストに格納する要素の型を表します
サンプルコードは以下の通りです。
ArrayList<String> list = new ArrayList<>();
// リストの最後に要素を追加
list.add("a"); // [a]
list.add("b"); // [a, b]
// インデックス1(2番目)に要素を追加
list.add(1, "c"); // [a, c, b]
// リスト内に"b"があるか判定
list.contains("b"); // true
// インデックス1(2番目)の要素を取得
list.get(1); // "c"
// インデックス1(2番目)の要素を削除
list.remove(1); // [a, b]
// リスト内の要素の数を取得
list.size(); // 2
ArrayListの初期化方法
配列の場合、初期化子「{}」を使って、配列の中身を初期化する方法があります。
ArrayListの場合初期化子による初期化はできないため、次のようなメソッドを使います。
- List.of()
- Arrays.asList()
どちらもリストを作成する処理です。
ただし、このメソッドで作られたリストは、要素の追加や削除などができません。
なお、List.of()は要素の置き換えもできず、nullも含められません。Arrays.asList()は要素数を変更できませんが、setメソッドで要素を置き換えることはできます。
List.of()が使えるのはJava 9以降です。Java 8の環境ではArrays.asList()を使ってください。
そこで、作成したリストを丸ごとArrayListのコンストラクタに渡すことで、変更可能なArrayListを取得できます。
サンプルコードは以下の通りです。
ArrayList<String> list1 = new ArrayList<>(List.of("a1", "b1", "c1"));
ArrayList<String> list2 = new ArrayList<>(Arrays.asList("a2", "b2", "c2"));
よくわからない場合でも、サンプルコードを真似することで初期化の処理ができますので、参考にしてください。
ArrayListで二次元リストを扱う方法
配列では、次のようにして「配列の配列(=二次元配列)」を作成できます。
int[][] array = new int[2][3]; array[1][2] = 10; // 2行目・3列目に値を代入
同様に、ArrayListでも「リストのリスト(=二次元リスト)」を扱えます。
考え方は配列の場合と同じですが、各要素にはメソッドでアクセスする点が異なります。
次のサンプルを参考にしてください。
ArrayList<String> list1 = new ArrayList<>(List.of("a", "b"));
ArrayList<String> list2 = new ArrayList<>(List.of("c", "d"));
ArrayList<ArrayList<String>> list = new ArrayList<>();
list.add(list1);
list.add(list2);
for(int i = 0; i < list.size(); i++){
ArrayList<String> l = list.get(i);
for(int j = 0; j < l.size(); j++){
System.out.println(l.get(j));
}
}
リストを扱うためのリストなので、< >の中がリスト(ArrayList)になっているのがポイントです。
実行結果は、
a b c d
となります。
AI連携の前に、問い合わせ一覧の中身を確認する
既存のJavaシステムから問い合わせを取り出し、AIで分類する処理を作るとします。ArrayListに値を入れられても、そのままAIへ送ってよいとは限りません。まずは架空の問い合わせで、入力の扱いを決めてみましょう。
空のデータと重複をどう扱うか決める
例えば「配送状況を知りたい」「請求書を再発行してほしい」に、null・空文字・同じ文面を混ぜた一覧を用意します。ArrayListにはnullも重複も入るため、業務に合う条件を別に決める必要があります。
| 試す入力 | 確認すること |
|---|---|
| 0件の一覧 | get(0)を呼ぶ前に空かを調べ、送信せず終了できるか |
| null・空文字 | 除外するか確認対象に回すかを決め、文字列の操作前にnullを確認する |
| 同じ文面が2件 | 別の問い合わせかもしれないため、文面だけで削除せず問い合わせIDなどで区別する |
| 想定より多い件数 | 送信先の入力上限に合わせて分割し、未処理・処理済みを追跡できるか |
同じ文面でも問い合わせ主や受付時刻が違えば、別の案件として扱うことがあります。実際の連携では本文だけのリストではなく、IDなども保持し、AIの分類結果を元の問い合わせと対応させます。
AIの回答を元の問い合わせと対応させる
例えば、問い合わせ101と102をAIへ送り、102の処理だけが先に終わる場合を考えてみてください。回答を返ってきた順にリストへ追加すると、元の問い合わせ順とはずれることがあります。
問い合わせIDと処理結果を組にして管理すると、再試行した結果や、分類できなかった案件も追いやすくなります。ArrayListの位置だけで対応づけず、IDの一致や結果の件数を確認しましょう。
また、ArrayListの要素数と、AIへ一度に送れる文章量は別の問題です。件数が少なくても長文が含まれる場合があります。送信先の上限に合わせて分割し、実際の顧客情報を渡す前に利用ルールも確認します。
FDEが既存のJavaシステムにAIを組み込む場合、こうしたデータの受け渡しも実装の一部になります。ArrayListはその基礎として使えますが、データを入れるだけで欠損や対応関係を解決してくれるわけではありません。
ArrayListについてよくある質問
空のリストから値を取り出すとどうなる?
空のリストにget(0)を使うと、IndexOutOfBoundsExceptionが発生します。先頭の要素を取り出す前にisEmpty()で空かどうかを確認すると、この場合の処理を分けられます。
最初に「10」と指定したら、要素が10個入る?
new ArrayList<>(10)の10は初期容量であり、要素数ではありません。作成直後のsize()は0です。値を入れるにはaddメソッドを使います。
整数のリストから「1」を消したいときは?
remove(1)と書くと、インデックス1、つまり2番目の要素が削除されます。値が1の要素を削除したいときは、remove(Integer.valueOf(1))と書きます。同じ値が複数ある場合は、最初の1件が削除されます。
まとめ
ArrayListは、配列に似た性質を持っていますが、後から要素を追加できる点が最大の違いです。
要素数を予測できないケースは多々あるため、ArrayListはかなり頻繁に使うことになります。
ただし、やや扱い方にくせがあるため、使いこなせるようになるにはある程度慣れが必要です。
使いどころが多く便利な機能なので、身に着けておくと役に立つこと間違いなしです。
ぜひ皆さんも練習してみてください。
また、Java初心者の課題としてよく挙げられるのが、自分の作りたいものがわからないことです。
その悩みを解決するための手順や、初心者の方でもJavaで作れるものについて詳しく解説していますので、参考にしてください。