Java プログラミングでは、データ構造が重要な役割を果たします。これらのデータ構造はデータの整理と管理に役立ち、コードをより効率的で保守しやすくします。その 1 つは、LinkedList
挿入および削除操作を効率的に実行できる柔軟なデータ構造であることです。このブログでは、基本概念から高度な使用法まで Java を掘り下げLinkedList
、包括的な情報を紹介します。
1. リンクリストとは何ですか?
LinkedList
Java における二重リンクリストのデータ構造です。これは一連のノードで構成され、各ノードにはデータ要素と、前後のノードへの参照が含まれます。この構造により、LinkedList
配列のようなメモリ空間の再割り当てが必要ないため、挿入および削除操作が非常に効率的になります。
2. LinkedList の作成と初期化
Java では、次を使用して作成および初期化できますLinkedList
。
LinkedList<String> linkedList = new LinkedList<>();
LinkedList
これにより、文字列要素を格納するための空のオブジェクトが作成されます。次のように、既存のコレクションを使用して初期化することもできますLinkedList
。
List<String> stringList = new ArrayList<>();
stringList.add("苹果");
stringList.add("香蕉");
LinkedList<String> linkedList = new LinkedList<>(stringList);
これにより、「apple」と「banana」を含む要素が作成されますLinkedList
。
3. 基本操作
3.1 要素の追加
3.1.1add
方法
要素を に追加するには、メソッドをLinkedList
使用できます。add
リストの最後に要素を追加します。
linkedList.add("橙子");
3.1.2 指定位置に要素を追加
add
このメソッドを使用して、指定した位置に要素を挿入することもできます。指定された位置は、0 から始まるインデックスによって決まります。
linkedList.add(1, "葡萄"); // 在索引 1 处插入 "葡萄"
3.2 要素の取得
3.2.1get
方法
LinkedList
の要素を取得するには、get
要素のインデックスを指定するメソッドを使用できます。
String fruit = linkedList.get(0); // 获取第一个元素
3.3 要素の削除
3.3.1remove
方法
から要素を削除するには、メソッドをLinkedList
使用できます。remove
削除する要素または削除する要素のインデックスを指定できます。
linkedList.remove("香蕉"); // 删除 "香蕉"
linkedList.remove(1); // 删除索引 1 处的元素
4. LinkedList をトラバースする
トラバースはLinkedList
さまざまな方法で実行できますが、最も一般的なのはfor-each
ループまたはイテレータを使用することです。
4.1for-each
ループの使用
for (String fruit : linkedList) {
System.out.println(fruit);
}
4.2 イテレータの使用
Iterator<String> iterator = linkedList.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
}
5. 特別な操作
5.1 先頭と末尾に要素を追加する
LinkedList
先頭と末尾に要素を効率的に追加できます。
5.1.1 先頭に要素を追加する
linkedList.addFirst("草莓");
5.1.2 最後に要素を追加する
linkedList.addLast("樱桃");
5.2 特定の位置に要素を挿入する
LinkedList
特定の位置に要素を挿入することもできます。
linkedList.add(2, "葡萄"); // 在索引 2 处插入 "葡萄"
5.3 要素の置換
set
メソッドを使用して、 内の要素を置き換えることができますLinkedList
。
linkedList.set(1, "蓝莓"); // 将索引 1 处的元素替换为 "蓝莓"
6. パフォーマンスに関する考慮事項
6.1 ArrayListとの比較
の使用を検討する場合、パフォーマンスのトレードオフが発生しますLinkedList
。と比較してArrayList
、LinkedList
多数の要素を移動する必要がないため、挿入および削除操作が一般的に高速になります。ただし、リンクされたリストを先頭または末尾から開始して走査する必要があるため、要素にランダムにアクセスする場合はパフォーマンスが低下します。
6.2 時間計算量
- 要素の追加と削除: 平均時間計算量は O(1) (位置がわかっている場合)、最悪の場合は O(n) (リンクされたリスト全体を走査する必要がある場合)。
- 要素の取得: 平均時間計算量は O(n/2) です (平均的な場合、リンク リストの半分を走査する必要があります)。
- 要素へのランダム アクセス: 最悪の場合は O(n) (リンク リスト全体を最初または最後から走査する必要があります)。
7. 使用上の注意
を使用する場合はLinkedList
、次の点に注意する必要があります。
LinkedList
スレッドセーフではありません。複数のスレッドで使用する場合は、適切な同期措置を講じるか、スレッドセーフな代替手段を検討する必要があります。- 過度のランダムアクセスはパフォーマンスが低下するため避けてください。頻繁なランダムアクセスが必要な場合は、使用を検討してください
ArrayList
。 LinkedList
大量のメモリを消費する可能性があるため、large を使用する場合は注意してください。
8. 高度な使い方
8.1 二重リンクリスト
LinkedList
は二重リンク リストの実装です。これは、各ノードに前のノードと次のノードへの参照が含まれていることを意味します。この双方向接続により、リンクされたリストを前方と後方の両方で非常に効率的に移動できます。二重リンクリストの高度な使用例をいくつか示します。
8.1.1 リンクされたリストを逆順に走査する
LinkedList
の双方向性により、逆順のトラバースが容易になります。リンク リストの末尾からトラバースを開始し、リンク リストの先頭に到達するまで前のノードの参照をたどり続けることができます。
LinkedList<String> linkedList = new LinkedList<>();
// 添加元素到链表
// ...
// 逆序遍历链表
ListIterator<String> iterator = linkedList.listIterator(linkedList.size());
while (iterator.hasPrevious()) {
String item = iterator.previous();
System.out.println(item);
}
8.1.2 特定の位置に要素を挿入する
二重リンク リストのプロパティにより、両方向にトラバースできるため、特定の場所への要素の挿入がより効率的になります。これにより、リンクされたリストの途中に要素を挿入する必要がある場合にパフォーマンスが向上します。
LinkedList<String> linkedList = new LinkedList<>();
// 添加元素到链表
// ...
// 在中间位置插入元素
ListIterator<String> iterator = linkedList.listIterator(linkedList.size() / 2); // 在中间位置开始
iterator.add("新元素");
8.2 循環リンクリスト
LinkedList
また、循環リンク リストとしても使用できます。つまり、リンク リストの最後のノードが最初のノードを指し、閉ループを形成します。この構造は、循環キューなどの特定のアルゴリズムやデータ構造で非常に役立ちます。
LinkedList<String> circularList = new LinkedList<>();
circularList.add("元素1");
circularList.add("元素2");
circularList.add("元素3");
// 构建循环链表,将最后一个元素指向第一个元素
circularList.getLast().setNext(circularList.getFirst());
// 遍历循环链表
Node<String> currentNode = circularList.getFirst();
do {
System.out.println(currentNode.getData());
currentNode = currentNode.getNext();
} while (currentNode != circularList.getFirst());
8.3 キューおよびスタックとしてのリンクされたリスト
LinkedList
キューおよびスタックの実装として使用できます。キューに対する先入れ先出し (FIFO) 操作とスタックに対する後入れ先出し (LIFO) 操作をサポートします。以下は、LinkedList
を使用してキューとスタックを実装する方法の例です。
8.3.1 リンクリストを使用したキューの実装
LinkedList<String> queue = new LinkedList<>();
// 入队
queue.offer("元素1");
queue.offer("元素2");
// 出队
String item = queue.poll();
8.3.2 リンクリストを使用したスタックの実装
LinkedList<String> stack = new LinkedList<>();
// 入栈
stack.push("元素1");
stack.push("元素2");
// 出栈
String item = stack.pop();
これらの高度な使用法は、LinkedList
さまざまなシナリオでの柔軟性と機能性を実証します。ニーズに応じて、二重リンク リストの機能を最大限に活用して問題を解決できます。
9. サンプルコード
以下をLinkedList
使用したサンプルコードをいくつか示します。
// 创建一个 LinkedList
LinkedList<String> linkedList = new LinkedList<>();
// 添加元素
linkedList.add("苹果");
linkedList.add("香蕉");
// 获取元素
String fruit = linkedList.get(0);
// 删除元素
linkedList.remove("香蕉");
// 遍历 LinkedList
for (String item : linkedList) {
System.out.println(item);
}
10. まとめ
LinkedList
これは Java の強力なデータ構造であり、挿入および削除操作が非常に効率的です。ただし、要素にランダムにアクセスするとパフォーマンスが低下するため、慎重に使用してください。LinkedList
このブログがJava コードを記述する際の理解と使用法、そして賢明な選択に役立つことを願っています。初心者でも経験豊富な開発者でも、マスタリングを行うことで、LinkedList
プログラミングの旅に新しいツールやテクニックが追加されます。