はじめに:Listを極めればJavaがもっとわかる!
Javaで最もよく使われるコレクションのひとつが「List」です。
Listは、順序を保ち、重複を許すという特徴を持ち、初心者からベテランまであらゆるプログラマーが日常的に使っています。
でも、「ArrayListとLinkedListの違いって何?」「Vectorってもう古いの?」と迷うこと、ありませんか?
この記事では、JavaのList系コレクションをわかりやすく比較・解説し、状況別の選び方も紹介します。
1. Listインターフェースとは?
✔ Listの基本ルール
JavaのListは以下のような特徴があります:
- 順序を保つ(インデックスで要素を操作)
- 重複を許す(同じ値を何度でも入れられる)
- null要素も許される(実装による)
1 2 3 4 5 6 |
List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("A"); // 重複OK System.out.println(list); // [A, B, A] |
2. よく使われるListの実装3選+α
① ArrayList:定番の基本形
- 内部構造:配列ベース(可変長)
- 特徴:ランダムアクセスに強い(O(1))
- 弱点:中間の挿入/削除が遅い(O(n))
- 用途:とにかく高速にアクセスしたいときに
1 2 3 4 |
List<String> list = new ArrayList<>(); list.add("apple"); list.get(0); // 素早く取得 |
② LinkedList:挿入と削除が得意!
- 内部構造:双方向リンク構造(ノードで管理)
- 特徴:中間や先頭/末尾の操作が速い
- 弱点:インデックスアクセスが遅い(O(n))
- 用途:リストの途中でたくさん追加・削除したいとき
1 2 3 4 |
LinkedList<String> list = new LinkedList<>(); list.addFirst("start"); list.addLast("end"); |
③ Vector:過去の遺産
- 内部構造:ArrayListに似ているが、すべて同期化されている
- 特徴:スレッドセーフ
- 弱点:処理が遅く、非推奨
- 用途:レガシーシステムなど、互換性が必要なときだけ
④ CopyOnWriteArrayList:読み取り多めに強い
- 内部構造:書き込み時にコピーが発生
- 特徴:スレッドセーフで安全
- 弱点:書き込みが多いと性能が落ちる
- 用途:読み込み中心のリスト操作(設定情報など)
3. Listの選び方:迷わないための判断基準
以下のチェックリストで、自分に合ったListがすぐ見つかります!
判断ポイント | 内容 | おすすめのList |
---|---|---|
ランダムアクセスが多い? | get(index) で頻繁に取得 | ArrayList |
中間の追加・削除が多い? | add(index, value) やremove(index) が頻繁 | LinkedList |
スレッド安全が必要? | 複数スレッドから同時アクセス | CopyOnWriteArrayList、同期ラッパー |
読み取りがほとんど? | 書き込みは少なく、参照が多い | CopyOnWriteArrayList |
両端の操作が多い? | addFirst() やremoveLast() など | LinkedList |
古いコードとの互換が必要? | Vectorを使っていた歴史的経緯あり | Vector(非推奨) |
4. コード例で使い分けを理解しよう
✔ ArrayList:アクセスがとにかく速い
1 2 3 4 5 |
List<String> fruits = new ArrayList<>(); fruits.add("apple"); fruits.add("banana"); System.out.println(fruits.get(1)); // banana |
✔ LinkedList:挿入・削除が得意
1 2 3 4 5 6 |
LinkedList<String> items = new LinkedList<>(); items.add("first"); items.add(1, "middle"); items.addLast("last"); items.removeFirst(); // "first"を削除 |
✔ CopyOnWriteArrayList:安全に読み取り
1 2 3 4 5 6 7 8 |
List<String> threadSafeList = new CopyOnWriteArrayList<>(); threadSafeList.add("read1"); threadSafeList.add("read2"); for (String item : threadSafeList) { System.out.println(item); threadSafeList.add("newItem"); // 安全に書き込み可能 } |
5. 性能と注意点:ここを知らずに使うと損!
✔ アクセス速度比較(目安)
操作内容 | ArrayList | LinkedList | CopyOnWriteArrayList |
---|---|---|---|
get(index) | 高速 O(1) | 遅い O(n) | 高速 O(1) |
add(index) | 遅い O(n) | 比較的速い | 遅い(全コピー) |
remove(index) | 遅い O(n) | 比較的速い | 遅い(全コピー) |
✔ 注意すべき落とし穴
- ArrayListでスレッド競合 → 同時アクセスでバグや例外
- LinkedListでランダムアクセス多用 → 思ったより遅い
- CopyOnWriteArrayListで書き込みが多い → コピーで激重
- Vectorを無意識に使う → 非推奨。新規コードでは使わない
- 同期ラッパーを使っても
for
文は同期必要!
6. よくあるミスとアンチパターン
ArrayList
で先頭への挿入を繰り返して遅くなるLinkedList
でランダムアクセス多用してパフォーマンス低下CopyOnWriteArrayList
をチャットアプリや大量書き込みで使って性能悪化Vector
を新しいコードで普通に使ってしまう(もう古い)
7. まとめ:どのListを選ぶ?フローチャートで整理!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
↓ ランダムアクセス多い? → Yes:ArrayList → No ↓ ↓ 中間での挿入・削除が多い? → Yes:LinkedList → No ↓ ↓ スレッドセーフが必要? → Yes:CopyOnWriteArrayList または同期ラッパー → No:ArrayList か LinkedList ↓ 書き込み少なくて読み取り中心? → Yes:CopyOnWriteArrayList → No:用途見直しを! |
おわりに:正しいList選びがあなたのJava力を変える!
Listはどの実装を使うかで、コードの読みやすさ・保守性・性能が大きく変わります。
まずは、
👉 「絶対にJavaプログラマーになりたい人へ。」
でListの基本をしっかりマスターしてください。
さらに、
- プログラムレビューを受けたい
- Javaの力を本気で仕事に活かしたい
- 転職に向けてスキルアップしたい
という方には、サイゼントアカデミー が全力でサポートします!
コメント