システムエンジニアの井上です。
今回は初学者がJavaを扱うにあたって混乱しがちなJavaのコレクションについて簡単に解説します。
目次
コレクションとは
配列のように複数の要素をまとめて管理できるものです。
配列とは違い、要素数の増減が可能なので一般的には配列よりコレクションが利用されることが多いです。
コレクションにはList、Map、Setの3種類あり、それぞれ以下のような特徴があります。
それぞれのコレクションに関して詳しく解説します。
List
Listは順序づけて要素が保持されるコレクションで、重複した値を保持することが可能です。
Listでは主にArrayListとLinkedListが使用されます。
ArrayList
ArrayListには主に以下の特徴があります。
- 特定の要素にアクセス(ランダムアクセス)する速度は速い
- 要素の追加、削除の速度は遅い(末尾以外)
ArrayListは配列をベースにしたリストで、データを連続したスペースに順番に並べて保存しています。
ArrayListを例えるならば駐車場のようなもので、そこに車(データ)を順番に停めているイメージです。
駐車場なので「2番目の車を見せて」と指示をすればすぐに見つけることができます(アクセスが速い)
しかし、もし真ん中に新しい車を入れたい時は、それ以降の他の車をずらす必要があります。
そのため、末尾以外の追加や削除の速度は遅くなります。
ArrayList<String> list = new ArrayList<>();
list.add("Red");
list.add("Blue");
list.add("White");
// ランダムアクセスは速い!
System.out.println(list.get(1)); // "Blue"
// 末尾以外の追加や削除は遅い!
list.add(1, "Black");
list.remove(2);
LinkedList
LinkedListには主に以下の特徴があります。
- 特定の要素にアクセス(ランダムアクセス)する速度は遅い
- 要素の追加、削除の速度は速い
LinkedListは「データ同士を鎖でつないでいる」ような構造です。
要素は鎖でつながった自分の前後の要素のみを知っており、自分が何番目なのか把握していないため、特定の要素へアクセスする際は先頭もしくは末尾から順番に数えていく必要があります。
そのため、ランダムアクセスはArrayListと比べて遅くなります。
しかし、要素の追加や削除に関しては要素をつなぐ鎖をつけ外しするだけで完了するので高速で実現できます。
List<String> list = new LinkedList<>();
list.add("Red");
list.add("Blue");
list.add("White");
// ランダムアクセスは遅い!
System.out.println(list.get(1)); // "Blue"
// 追加や削除は速い!
list.add(1, "Black");
list.remove(2);
Listのまとめ
- ArrayListはランダムアクセスが速く、要素の追加・削除が遅い(末尾以外)。
- LinkedListはランダムアクセスが遅く、要素の追加・削除が速い。
Set
Setは主に順序づけなしで要素が保持されるコレクションで、重複した値を保持することができません。
Setに関してはHashSetとTreeSetについて解説します。
HashSet
HashSetは名前の通りハッシュ(Hash)という仕組みを使っています。
中身は「ハッシュテーブル」という箱のような構造で、要素を順番関係なく保持しています。
そして重複したデータを登録することはできません。
HashSet<String> set = new HashSet<>();
set.add("Red");
set.add("Blue");
set.add("White");
// 検索が速い!
set.contains("Red"); // true
TreeSet
TreeSetはSetなのですが、追加したデータを自動的にソートして保存しています。
そのため、範囲検索をすることが可能です。(HashSetではできない)
登録や削除の際にソートを行うため、HashSetと比べると処理速度は少し遅いです。
TreeSet<Integer> set = new TreeSet<>();
set.add(70);
set.add(20);
set.add(50);
System.out.println(set); // [20, 50, 70] ←自動で昇順ソートされている!
// 範囲検索できる!
System.out.println(set.subSet(10, 60)); // [20, 50]
Setのまとめ
- HashSetは順序はないが処理が速い。
- TreeSetは順序があり、範囲検索ができるが処理が少し遅い。
Map
Mapはキー(key)と値(value)を紐づけて要素を保持するコレクションです。キーの重複はできません。
Mapに関してはHashMap、LinkedHashMap、TreeMapについて解説します。
HashMap
HashMapは最もよく使われるMapです。
内部的には「ハッシュテーブル」という仕組みを使っており、要素の順番は保証されません。
検索や追加などの処理速度も速いです。
Map<String, Integer> prices = new HashMap<>();
prices.put("apple", 100);
prices.put("banana", 200);
prices.put("orange", 150);
System.out.println(prices); // {orange=150, banana=200, apple=100} ← 順番ランダム
LinkedHashMap
LinkedHashMapはHashMapに順序の記録機能を加えたクラスです。
要素を追加した順番(またはアクセス順)を保ちながらデータを保持します。
Map<String, Integer> prices = new LinkedHashMap<>();
prices.put("apple", 100);
prices.put("banana", 200);
prices.put("orange", 150);
System.out.println(prices); // {apple=100, banana=200, orange=150} ← 追加順を保持
TreeMap
TreeMapはキーを自動的にソートして管理するクラスです。
処理速度は比較的遅いですが、ソートされたMapが必要な場合に利用します。
Map<String, Integer> prices = new TreeMap<>();
prices.put("orange", 150);
prices.put("apple", 100);
prices.put("banana", 200);
System.out.println(prices); // {apple=100, banana=200, orange=150} ← 自動ソート!
Mapのまとめ
- HashMapは順序がなく、速度重視のMapで一般的に利用されている。
- LinkedHashMapは順番を保ちたい場合に利用する。
- TreeMapはキーを自動でソートしたい場合に利用する。
最後に
Javaのコレクションに関して簡単に解説しました。
Javaのコレクションは、データの扱い方に応じて最適なクラスを選ぶことが大切です。
- List:順序を保ちながら重複を許す
- Set:重複を許さない集合
- Map:キーと値をペアで管理
さらに、ArrayList・LinkedList・HashSet・TreeSet・HashMap・LinkedHashMap・TreeMapといった実装ごとに、
「速度」「順序」「ソート」「重複可否」などの特徴が異なります。
コレクションはどのアプリケーション開発でも欠かせない基礎です。
仕組みを理解しながら使い分けを意識することで、
あなたのコードはより「読みやすく」「効率的」になります。
もっと詳しく学習したくなった方は公式ドキュメントなどを参考に理解を深めていってはいかがでしょうか。
みなさまの参考になれば幸いです。