はじめに
Javaで複数のデータを扱うときに登場する代表的な選択肢が「配列(Array)」と「List」です。しかし、どちらを使うべきか迷った経験はないでしょうか?
特に初心者の方にとっては、両者の違いや使い分けの基準が曖昧に感じられることも多いはずです。
この記事では、Javaエンジニア歴10年以上の筆者が、配列とListの違い、使い分けの基準、実践例まで丁寧に解説します。パフォーマンスや柔軟性、メンテナンス性を踏まえ、適切な選択ができるようになります。
配列の特徴と使いどころ
基本的な特徴
配列は、Javaにおける最も基本的なデータ構造です。あらかじめ要素数を指定して宣言し、同じ型のデータを連続して格納できます。
int[] numbers = new int[5];
主な特徴は以下のとおりです。
- 要素数は固定:一度サイズを指定すると変更できません。
- インデックスによる高速アクセス:0番目から始まるインデックスで直接アクセスできるため、読み書きが高速です。
- プリミティブ型に対応:
int
、double
などの値をそのまま格納でき、ボクシングのオーバーヘッドがありません。
配列を使うべきケース
配列が適しているのは、以下のようなシンプルでパフォーマンス重視のケースです。
- 要素数が変化しない場面(例:曜日、月の名前など定数的なデータ)
- リアルタイム処理など高パフォーマンスが要求される場面(例:画像処理や音声処理)
- プリミティブ型の大量処理が必要な場合(ボクシングによるパフォーマンス劣化を回避)
Listの特徴と使いどころ
基本的な特徴
List
は、Javaのコレクションフレームワークの中でも汎用性が高く、最もよく使われるインターフェースの1つです。中でもArrayList
は代表的な実装クラスです。
List<Integer> numbers = new ArrayList<>();
numbers.add(10);
主な特徴は以下のとおりです。
- サイズが可変:要素の追加・削除が柔軟に行えます。
- 便利な操作メソッドが豊富:
add
、remove
、contains
、sort
など、日常的なデータ操作に便利な機能が揃っています。 - Stream APIとの親和性が高い:
list.stream()
を使えば、ラムダ式による柔軟なデータ処理が可能です。
Listを使うべきケース
Listが適しているのは、以下のような場面です。
- 要素数が動的に変化する可能性がある(例:ユーザー入力、データベースの検索結果)
- ソート、検索、フィルタなどの処理が頻繁に発生する(例:商品一覧やログのフィルタリング)
- 可読性や保守性を重視したビジネスロジックの実装(例:業務アプリケーションでのデータ管理)
配列とListの比較表
配列とList
(主にArrayList
)の違いを、用途別にわかりやすく比較しました。選定時の判断材料としてご活用ください。
比較項目 | 配列 | List(ArrayListなど) |
---|---|---|
サイズの可変性 | 固定(後から変更不可) | 可変(必要に応じて拡張・縮小可能) |
プリミティブ型対応 | 対応(int[] 、double[] など) | 非対応(Integer 、Double などラッパークラスが必要) |
アクセス速度 | 高速(インデックスアクセスが直感的で軽量) | やや遅い(内部でバッファ処理が行われる) |
操作の柔軟性 | 低い(メソッドがほとんどない) | 高い(add やremove など多数の操作が可能) |
可読性・保守性 | 単純で軽量だが拡張性は低い | 構造がわかりやすく、保守性・拡張性に優れる |
Stream API対応 | Arrays.stream() が必要 | list.stream() でそのまま利用可能 |
Listのアクセス速度は「やや遅い」と記述していますが、ArrayList
のアクセスはO(1)
であり、要素数が少なければ実質的な差はほとんどないです。
判断に迷ったら?使い分けチェックリスト
以下のチェックポイントを参考にすれば、配列とListのどちらを使うべきかすぐに判断できます。
- ✅ 要素数があらかじめ決まっていて変化しない
→ 配列 を使うのが適しています。 - ✅
int
やdouble
などのプリミティブ型を大量に高速処理したい
→ 配列 がボクシングのコストを避けられるため有利です。 - ✅ 要素の追加・削除が頻繁に発生する
→ List(ArrayList
など)が柔軟で便利です。 - ✅ ソート・フィルター・検索といった操作を頻繁に行う
→ List のメソッドやStream APIとの親和性が役立ちます。 - ✅ コードの可読性や将来的な保守性を重視したい
→ List を使うと、後からの拡張や変更がしやすくなります。
実践例:配列とListの使い方比較
🔹 配列を使った例
String[] fruits = {"apple", "banana", "orange"};
for (String fruit : fruits) {
System.out.println(fruit);
}
ポイント:
- 要素数は固定。
for-each
でのループが簡潔。- 高速かつメモリ効率が良い。
🔸 Listを使った例
List<String> fruits = new ArrayList<>();
fruits.add("apple");
fruits.add("banana");
fruits.add("orange");
fruits.remove("banana"); // 要素の削除
fruits.sort(Comparator.naturalOrder()); // ソート
fruits.forEach(System.out::println); // 出力
ポイント:
- 要素の追加や削除が自在。
- ソートや検索もメソッド1つで実現可能。
- Stream APIとの連携もスムーズ。
よくある質問(FAQ)
List<int>
が使えないのはなぜ?-
Javaのジェネリクス(Generics)は、
int
やdouble
などのプリミティブ型を直接扱うことができません。そのため、List<Integer>
のようにラッパークラス(この場合はInteger
)を使う必要があります。 - 配列とListを相互に変換するには?
-
配列 → List に変換する方法:
List<String> list = Arrays.asList(array);
List → 配列 に変換する方法:
String[] array = list.toArray(new String[list.size()]);
まとめ
配列とListは、どちらもJavaで頻繁に使われるデータ構造ですが、それぞれに明確な特長があります。重要なのは、用途や要件に応じて正しく使い分けることです。
- 固定長で高速処理が求められる場合 → 配列
- 柔軟性・保守性・可読性を重視したい場合 → List
もし判断に迷う場合は、まずは扱いやすく柔軟なListから始めるのがおすすめです。必要に応じて、パフォーマンスを考慮して配列への置き換えを検討するとよいでしょう。
それぞれの特性を理解し、適材適所で使いこなすことで、より効率的でメンテナンス性の高いコードを書くことができます。