今回やること
LinkedListは、先頭と末尾の操作を持つリストです。受付の待ち行列を作り、通常の人を末尾、優先対応を先頭へ追加します。
前提: Java入門 #15 - ArrayListで
add、remove、繰り返しを学んでいること。
先頭 ← [優先対応, Ada, Ken] → 末尾
| 操作 | 待ち行列での意味 |
|---|---|
addLast(value) | 通常受付を末尾へ追加 |
addFirst(value) | 優先対応を先頭へ追加 |
removeFirst() | 次の1人を先頭から取り出す |
remove(value) | 指定した人を取り消す |
1. 末尾へ追加する
LinkedList<String> queue = new LinkedList<>();
queue.addLast("Ada");
queue.addLast("Ken");
通常の受付順では、後から来た人を末尾へ追加します。現在は先頭がAda、末尾がKenです。
2. 先頭へ優先対応を入れる
queue.addFirst("優先対応");
待ち行列は[優先対応, Ada, Ken]になります。どちら側を操作するかがメソッド名で分かります。
3. 先頭を取り出す
if (!queue.isEmpty()) {
String next = queue.removeFirst();
System.out.println("対応開始: " + next);
}
空のLinkedListでremoveFirst()を呼ぶとNoSuchElementExceptionです。先にisEmpty()で確認します。
4. 名前を指定して削除する
queue.remove("Ken");
remove(value)は最初に見つかった同じ値を削除し、削除できたかをbooleanで返します。受付取消の成否を確認したい場合は戻り値を使えます。
完成コードを動かす
LinkedListDemo.javaとして保存します。
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList<String> queue = new LinkedList<>();
queue.addLast("Ada");
queue.addLast("Ken");
queue.addFirst("優先対応");
if (!queue.isEmpty()) {
String next = queue.removeFirst();
System.out.println("対応開始: " + next);
}
boolean canceled = queue.remove("Ken");
System.out.println("Kenの取消: " + canceled);
System.out.println("待ち人数: " + queue.size());
for (String name : queue) {
System.out.println("待機中: " + name);
}
}
}
javac LinkedListDemo.java
java LinkedListDemo
操作後の状態を追います。
| 操作後 | 待ち行列 |
|---|---|
| Ada、Kenを追加 | [Ada, Ken] |
| 優先対応を先頭へ | [優先対応, Ada, Ken] |
| 先頭を対応開始 | [Ada, Ken] |
| Kenを取消 | [Ada] |
ArrayListとの短い違い
| 主な用途 | 選択の目安 |
|---|---|
| indexで何度も参照する一般的なリスト | まずArrayList |
| 先頭・末尾を明示して待ち行列のように操作 | LinkedListも候補 |
内部実装だけで性能を決めず、実際の操作とデータ量で選びます。通常のリストなら、まずArrayListで問題ありません。
ArrayListとLinkedListはどちらもListの基本操作を提供します。ただしaddFirstやremoveFirstのようにLinkedListの端を明示する操作を使う場合、変数型もLinkedListにすると利用できる操作が分かりやすくなります。インターフェースによる契約の考え方は#23で詳しく学びます。
成功確認
対応開始: 優先対応
Kenの取消: true
待ち人数: 1
待機中: Ada
先頭・末尾の追加、先頭の取り出し、値による削除が順に反映されれば成功です。
よくあるつまずき
空の行列からremoveFirstする
要素がなければ例外です。isEmpty()で確認してから取り出します。
addとaddFirstを混同する
通常のaddは末尾への追加です。どちら側かを明示したい待ち行列ではaddFirst、addLastを使うと読みやすくなります。
LinkedListなら常に速いと思う
操作位置や探索の有無で変わります。性能比較を暗記して選ばず、用途を先に決めます。
練習
印刷待ちの文書名をLinkedList<String>へ入れてください。通常文書を末尾、緊急文書を先頭へ追加し、1件印刷した後の待ち行列を表示します。
次のステップ
Java入門 #17 - HashMapで、順番ではなくキーから値を取り出すコレクションを学びます。