Java LinkedList完全ガイド:作成、操作、ArrayListとの比較
Java LinkedList
JavaのLinkedListを効率的なデータ操作に活用する方法を、実践的なコード例とベストプラクティスで解説します。
JavaコレクションフレームワークのLinkedListクラスは双方向リンクリストを実装します。各要素(ノード)は3つのフィールドを持ちます:
- prev - 前のノードへの参照(最初の要素はnull)
- next - 次のノードへの参照(最後の要素はnull)
- data - ノードに格納される実際の値
Java LinkedListの作成
特定の要素型でLinkedListをインスタンス化します:
LinkedList<Type> list = new LinkedList<>();
例:
// Integer型のリスト
LinkedList<Integer> numbers = new LinkedList<>();
// String型のリスト
LinkedList<String> words = new LinkedList<>();
例:JavaでのLinkedList作成
import java.util.LinkedList;
class Main {
public static void main(String[] args){
LinkedList<String> animals = new LinkedList<>();
animals.add("Dog");
animals.add("Cat");
animals.add("Cow");
System.out.println("LinkedList: " + animals);
}
}
出力
LinkedList: [Dog, Cat, Cow]
このコードは、add()で3つの要素を追加した基本的なanimalsというLinkedListを示しています。
Java LinkedListの仕組み
配列とは異なり、ノードはメモリ上に分散配置され、リンクで繋がれています。以下の図は3つのノードとその接続を示しています。

- Dog - 最初のノード、prev = null、next = Cat
- Cat - 中間ノード、prev = Dog、next = Cow
- Cow - 最後のノード、prev = Cat、next = null
より詳細についてはLinked Listの記事を参照してください。
LinkedListの主要メソッド
最も頻繁に使用される操作は以下の通りです:
- 要素の追加
- 要素へのアクセス
- 要素の更新
- 要素の削除
1. 要素の追加
add()でノードを追加し、オプションでインデックスを指定できます:
import java.util.LinkedList;
class Main {
public static void main(String[] args){
LinkedList<String> animals = new LinkedList<>();
animals.add("Dog");
animals.add("Cat");
animals.add("Cow");
System.out.println("LinkedList: " + animals);
animals.add(1, "Horse");
System.out.println("更新後のLinkedList: " + animals);
}
}
出力
LinkedList: [Dog, Cat, Cow] 更新後のLinkedList: [Dog, Horse, Cat, Cow]
2回目のadd()はインデックス1に"Horse"を挿入し、以降の要素をシフトさせます。
2. 要素へのアクセス
get()でインデックスにより要素を取得します:
import java.util.LinkedList;
class Main {
public static void main(String[] args){
LinkedList<String> languages = new LinkedList<>();
languages.add("Python");
languages.add("Java");
languages.add("JavaScript");
System.out.println("LinkedList: " + languages);
String str = languages.get(1);
System.out.print("インデックス1の要素: " + str);
}
}
出力
LinkedList: [Python, Java, JavaScript] インデックス1の要素: Java
イテレーションはiterator()やlistIterator()でも可能で、高度な走査ができます。
3. 要素の更新
set()で特定インデックスの要素を置換します:
import java.util.LinkedList;
class Main {
public static void main(String[] args){
LinkedList<String> languages = new LinkedList<>();
languages.add("Java");
languages.add("Python");
languages.add("JavaScript");
languages.add("Java");
System.out.println("LinkedList: " + languages);
languages.set(3, "Kotlin");
System.out.println("更新後のLinkedList: " + languages);
}
}
出力
LinkedList: [Java, Python, JavaScript, Java] 更新後のLinkedList: [Java, Python, JavaScript, Kotlin]
4. 要素の削除
remove()でインデックス指定で要素を削除します:
import java.util.LinkedList;
class Main {
public static void main(String[] args){
LinkedList<String> languages = new LinkedList<>();
languages.add("Java");
languages.add("Python");
languages.add("JavaScript");
languages.add("Kotlin");
System.out.println("LinkedList: " + languages);
String removed = languages.remove(1);
System.out.println("削除された要素: " + removed);
System.out.println("更新後のLinkedList: " + languages);
}
}
出力
LinkedList: [Java, Python, JavaScript, Kotlin] 削除された要素: Python 新しいLinkedList: [Java, JavaScript, Kotlin]
その他の便利なメソッド
| メソッド | 説明 |
|---|---|
contains() | 値の存在確認 |
indexOf() | 最初の出現インデックス |
lastIndexOf() | 最後の出現インデックス |
clear() | すべての要素を削除 |
iterator() | Iteratorを提供 |
LinkedListとしてのQueueとDeque
LinkedListはQueueとDequeを実装しているため、FIFOとLIFO操作をサポートします。一般的なメソッドには以下があります:
| メソッド | 説明 |
|---|---|
addFirst() | 先頭に追加 |
addLast() | 末尾に追加 |
getFirst() | 先頭を覗く |
getLast() | 末尾を覗く |
removeFirst() | 先頭をポップ |
removeLast() | 末尾をポップ |
peek() | 削除せずに先頭を表示 |
poll() | 先頭を取得して削除 |
offer() | 末尾にエンキュー |
例:LinkedListとしてのQueue利用
import java.util.LinkedList;
import java.util.Queue;
class Main {
public static void main(String[] args){
Queue<String> languages = new LinkedList<>();
languages.add("Python");
languages.add("Java");
languages.add("C");
System.out.println("LinkedList: " + languages);
String first = languages.peek();
System.out.println("アクセスされた要素: " + first);
String removed = languages.poll();
System.out.println("削除された要素: " + removed);
System.out.println("poll()後のLinkedList: " + languages);
languages.offer("Swift");
System.out.println("offer()後のLinkedList: " + languages);
}
}
出力
LinkedList: [Python, Java, C] アクセスされた要素: Python 削除された要素: Python poll()後のLinkedList: [Java, C] offer()後のLinkedList: [Java, C, Swift]
例:LinkedListとしてのDeque利用
import java.util.LinkedList;
import java.util.Deque;
class Main {
public static void main(String[] args){
Deque<String> animals = new LinkedList<>();
animals.add("Cow");
System.out.println("LinkedList: " + animals);
animals.addFirst("Dog");
System.out.println("addFirst()後: " + animals);
animals.addLast("Zebra");
System.out.println("addLast()後: " + animals);
animals.removeFirst();
System.out.println("removeFirst()後: " + animals);
animals.removeLast();
System.out.println("removeLast()後: " + animals);
}
}
出力
LinkedList: [Cow] addFirst()後: [Dog, Cow] addLast()後: [Dog, Cow, Zebra] removeFirst()後: [Cow, Zebra] removeLast()後: [Cow]
LinkedListのイテレーション
拡張forループで簡潔に要素を走査できます:
import java.util.LinkedList;
class Main {
public static void main(String[] args){
LinkedList<String> animals = new LinkedList<>();
animals.add("Cow");
animals.add("Cat");
animals.add("Dog");
System.out.println("LinkedList: " + animals);
System.out.println("リンクリスト要素へのアクセス:");
for(String animal: animals){
System.out.print(animal + ", ");
}
}
}
出力
LinkedList: [Cow, Cat, Dog] リンクリスト要素へのアクセス: Cow, Cat, Dog,
LinkedList vs ArrayList
両クラスはListを実装しますが、パフォーマンス特性が異なります:
| LinkedList | ArrayList |
|---|---|
List、Queue、Dequeを実装 | Listを実装 |
| ノードがprev、data、nextを保持 | 配列スロットごとに単一要素 |
| 双方向リンク構造 | サイズ可変配列 |
| 位置既知時の挿入/削除はO(1) | インデックス後の挿入はシフトでO(n) |
| ランダムアクセスは走査でO(n) | 直接インデックスアクセスでO(1) |
注意: LinkedListはそのインターフェースのいずれかでインスタンス化可能です:
// List経由
List<String> animals1 = new LinkedList<>();
// Queue経由
Queue<String> animals2 = new LinkedList<>();
// Deque経由
Deque<String> animals3 = new LinkedList<>();
インターフェース参照を使用する場合、そのインターフェースで定義されたメソッドのみ利用可能になります。
Java
- Java演算子をマスター:種類、構文、実践例
- Javaコメント:種類、使い方、ベストプラクティス
- Java拡張forループをマスター:構文、例、ベストプラクティス
- Java文字列をマスター:生成、メソッド、ベストプラクティス
- Javaインターフェース完全ガイド:概念、実装、ベストプラクティス
- Java無名インナークラス完全ガイド:定義、構文、実践例
- Javaのtry-with-resourcesをマスターする:自動リソース管理の仕組みと活用法
- Javaアノテーション完全ガイド:種類、配置場所、実践例
- Javaアサーション完全ガイド:バグ早期発見とコード信頼性の向上
- Java Vectorの理解:使い方、特徴、ArrayListとの比較
- Java 8 完全クイックリファレンス:全新機能を網羅した決定版ガイド