[Java] Dequeに要素を追加する方法まとめ

JavaのDequeインターフェースは、両端から要素を追加・削除できるデータ構造です。

要素を追加する方法は主に4つあります。

addFirst(E e)は先頭に要素を追加し、addLast(E e)は末尾に追加します。

offerFirst(E e)offerLast(E e)も同様に先頭と末尾に追加しますが、addメソッドが例外をスローするのに対し、offerメソッドは失敗時にfalseを返します。

この記事でわかること
  • Dequeの基本的な使い方
  • addメソッドとofferメソッドの違い
  • ArrayDequeとLinkedListの特徴
  • スタックやキューとしての利用法
  • スレッドセーフなDequeの作成方法

目次から探す

Dequeに要素を追加する方法

JavaのDeque(双方向キュー)は、両端から要素を追加・削除できるデータ構造です。

ここでは、Dequeに要素を追加するための主要なメソッドについて解説します。

addFirst(E e)メソッド

addFirstの使い方

addFirstメソッドは、Dequeの先頭に要素を追加します。

以下のサンプルコードでは、ArrayDequeを使用して、整数を先頭に追加する例を示します。

import java.util.ArrayDeque;
import java.util.Deque;
public class App {
    public static void main(String[] args) {
        Deque<Integer> deque = new ArrayDeque<>();
        
        // 先頭に要素を追加
        deque.addFirst(10); // 10を追加
        deque.addFirst(20); // 20を追加
        
        // Dequeの内容を表示
        System.out.println(deque);
    }
}
[20, 10]

addFirstの注意点

  • addFirstメソッドは、Dequeが満杯の場合にIllegalStateExceptionをスローします。
  • nullを追加することはできません。

addLast(E e)メソッド

addLastの使い方

addLastメソッドは、Dequeの末尾に要素を追加します。

以下のサンプルコードでは、ArrayDequeを使用して、整数を末尾に追加する例を示します。

import java.util.ArrayDeque;
import java.util.Deque;
public class App {
    public static void main(String[] args) {
        Deque<Integer> deque = new ArrayDeque<>();
        
        // 末尾に要素を追加
        deque.addLast(10); // 10を追加
        deque.addLast(20); // 20を追加
        
        // Dequeの内容を表示
        System.out.println(deque);
    }
}
[10, 20]

addLastの注意点

  • addLastメソッドも、Dequeが満杯の場合にIllegalStateExceptionをスローします。
  • nullを追加することはできません。

offerFirst(E e)メソッド

offerFirstの使い方

offerFirstメソッドは、Dequeの先頭に要素を追加し、成功した場合はtrueを返します。

以下のサンプルコードでは、ArrayDequeを使用して、整数を先頭に追加する例を示します。

import java.util.ArrayDeque;
import java.util.Deque;
public class App {
    public static void main(String[] args) {
        Deque<Integer> deque = new ArrayDeque<>();
        
        // 先頭に要素を追加
        boolean result1 = deque.offerFirst(10); // 10を追加
        boolean result2 = deque.offerFirst(20); // 20を追加
        
        // Dequeの内容を表示
        System.out.println(deque);
        System.out.println("追加結果: " + result1 + ", " + result2);
    }
}
[20, 10]
追加結果: true, true

offerFirstとaddFirstの違い

  • offerFirstは、Dequeが満杯の場合でもfalseを返すため、例外が発生しません。
  • addFirstは、Dequeが満杯の場合に例外をスローします。

offerLast(E e)メソッド

offerLastの使い方

offerLastメソッドは、Dequeの末尾に要素を追加し、成功した場合はtrueを返します。

以下のサンプルコードでは、ArrayDequeを使用して、整数を末尾に追加する例を示します。

import java.util.ArrayDeque;
import java.util.Deque;
public class App {
    public static void main(String[] args) {
        Deque<Integer> deque = new ArrayDeque<>();
        
        // 末尾に要素を追加
        boolean result1 = deque.offerLast(10); // 10を追加
        boolean result2 = deque.offerLast(20); // 20を追加
        
        // Dequeの内容を表示
        System.out.println(deque);
        System.out.println("追加結果: " + result1 + ", " + result2);
    }
}
[10, 20]
追加結果: true, true

offerLastとaddLastの違い

  • offerLastは、Dequeが満杯の場合でもfalseを返すため、例外が発生しません。
  • addLastは、Dequeが満杯の場合に例外をスローします。

Dequeの追加メソッドの違い

Dequeには、要素を追加するためのさまざまなメソッドがありますが、それぞれのメソッドには異なる特性があります。

ここでは、主にaddメソッドofferメソッドの違い、例外処理の有無、パフォーマンスの違いについて解説します。

addメソッドとofferメソッドの違い

スクロールできます
メソッド名説明満杯時の挙動
addFirst(E e)先頭に要素を追加例外をスロー(IllegalStateException)
offerFirst(E e)先頭に要素を追加falseを返す
addLast(E e)末尾に要素を追加例外をスロー(IllegalStateException)
offerLast(E e)末尾に要素を追加falseを返す
  • addメソッドは、Dequeが満杯の場合に例外をスローします。

これに対して、offerメソッドは、満杯の場合でも例外をスローせず、falseを返します。

このため、offerメソッドは、エラーハンドリングが容易です。

例外処理の有無

  • addメソッドaddFirstaddLastは、Dequeが満杯の場合にIllegalStateExceptionをスローします。

これにより、プログラマはエラーを捕捉し、適切な処理を行う必要があります。

  • 一方、offerメソッドofferFirstofferLastは、満杯の場合に例外をスローせず、単にfalseを返します。

これにより、エラー処理が簡素化され、プログラムの流れを維持しやすくなります。

パフォーマンスの違い

  • addメソッドは、通常、offerメソッドよりもわずかに高いパフォーマンスを持つことがあります。

これは、例外処理が発生しない場合、addメソッドが直接的に要素を追加するためです。

  • ただし、offerメソッドは、例外処理を行わないため、特に満杯の状態が頻繁に発生する場合には、全体的なパフォーマンスが向上する可能性があります。

特に、エラーハンドリングが不要な場合、offerメソッドを使用することで、プログラムの安定性が向上します。

このように、addメソッドofferメソッドは、それぞれ異なる特性を持っており、使用する場面によって使い分けることが重要です。

Dequeの実装クラス

JavaのDequeは、さまざまな実装クラスを持っています。

ここでは、代表的な実装であるArrayDequeLinkedListについて、それぞれの特徴と要素追加の方法を解説します。

ArrayDeque

ArrayDequeの特徴

  • 動的配列: ArrayDequeは、内部的に動的配列を使用しており、要素の追加や削除が高速です。
  • スレッドセーフではない: ArrayDequeはスレッドセーフではないため、複数のスレッドから同時にアクセスする場合は、外部で同期を行う必要があります。
  • nullを許可しない: ArrayDequeにはnull要素を追加することができません。
  • メモリ効率: 配列を使用しているため、メモリのオーバーヘッドが少なく、効率的です。

ArrayDequeでの要素追加

ArrayDequeに要素を追加する方法は、addFirstaddLastofferFirstofferLastを使用します。

以下のサンプルコードでは、ArrayDequeを使用して要素を追加する例を示します。

import java.util.ArrayDeque;
import java.util.Deque;
public class App {
    public static void main(String[] args) {
        Deque<Integer> deque = new ArrayDeque<>();
        
        // 先頭に要素を追加
        deque.addFirst(10); // 10を追加
        // 末尾に要素を追加
        deque.addLast(20); // 20を追加
        
        // Dequeの内容を表示
        System.out.println(deque);
    }
}
[10, 20]

LinkedList

LinkedListの特徴

  • 双方向リンクリスト: LinkedListは、双方向リンクリストとして実装されており、要素の追加や削除が容易です。
  • スレッドセーフではない: LinkedListもスレッドセーフではないため、複数のスレッドから同時にアクセスする場合は、外部で同期を行う必要があります。
  • nullを許可: LinkedListにはnull要素を追加することができます。
  • メモリオーバーヘッド: 各要素が次の要素と前の要素へのポインタを持つため、メモリのオーバーヘッドが大きくなることがあります。

LinkedListでの要素追加

LinkedListに要素を追加する方法も、addFirstaddLastofferFirstofferLastを使用します。

以下のサンプルコードでは、LinkedListを使用して要素を追加する例を示します。

import java.util.Deque;
import java.util.LinkedList;
public class App {
    public static void main(String[] args) {
        Deque<Integer> deque = new LinkedList<>();
        
        // 先頭に要素を追加
        deque.addFirst(10); // 10を追加
        // 末尾に要素を追加
        deque.addLast(20); // 20を追加
        
        // Dequeの内容を表示
        System.out.println(deque);
    }
}
[10, 20]

このように、ArrayDequeLinkedListはそれぞれ異なる特性を持っており、使用する場面によって適切な実装を選択することが重要です。

Dequeの応用例

Dequeは、その特性を活かしてさまざまなデータ構造として利用できます。

ここでは、スタック、キュー、双方向キューとしての利用方法について解説します。

スタックとしての利用

Dequeは、スタックとして利用することができます。

スタックは、LIFO(Last In, First Out)方式で要素を管理するデータ構造です。

スタック操作における要素追加

スタックとして利用する場合、addFirstメソッドを使用して要素を追加します。

以下のサンプルコードでは、ArrayDequeを使用してスタック操作を行う例を示します。

import java.util.ArrayDeque;
import java.util.Deque;
public class App {
    public static void main(String[] args) {
        Deque<Integer> stack = new ArrayDeque<>();
        
        // スタックに要素を追加
        stack.addFirst(10); // 10を追加
        stack.addFirst(20); // 20を追加
        
        // スタックの内容を表示
        System.out.println(stack);
        
        // スタックから要素を取り出す
        int topElement = stack.removeFirst(); // 20を取り出す
        System.out.println("取り出した要素: " + topElement);
        System.out.println(stack);
    }
}
[20, 10]
取り出した要素: 20
[10]

キューとしての利用

Dequeは、キューとしても利用できます。

キューは、FIFO(First In, First Out)方式で要素を管理するデータ構造です。

キュー操作における要素追加

キューとして利用する場合、addLastメソッドを使用して要素を追加します。

以下のサンプルコードでは、ArrayDequeを使用してキュー操作を行う例を示します。

import java.util.ArrayDeque;
import java.util.Deque;
public class App {
    public static void main(String[] args) {
        Deque<Integer> queue = new ArrayDeque<>();
        
        // キューに要素を追加
        queue.addLast(10); // 10を追加
        queue.addLast(20); // 20を追加
        
        // キューの内容を表示
        System.out.println(queue);
        
        // キューから要素を取り出す
        int frontElement = queue.removeFirst(); // 10を取り出す
        System.out.println("取り出した要素: " + frontElement);
        System.out.println(queue);
    }
}
[10, 20]
取り出した要素: 10
[20]

双方向キューとしての利用

Dequeは、双方向キューとしても利用できます。

双方向キューは、両端から要素を追加・削除できるデータ構造です。

双方向キューでの要素追加の利点

双方向キューを使用することで、両端からの操作が可能になり、柔軟なデータ管理が実現します。

以下のサンプルコードでは、LinkedListを使用して双方向キュー操作を行う例を示します。

import java.util.Deque;
import java.util.LinkedList;
public class App {
    public static void main(String[] args) {
        Deque<Integer> deque = new LinkedList<>();
        
        // 両端に要素を追加
        deque.addFirst(10); // 先頭に10を追加
        deque.addLast(20);  // 末尾に20を追加
        
        // Dequeの内容を表示
        System.out.println(deque);
        
        // 両端から要素を取り出す
        int firstElement = deque.removeFirst(); // 10を取り出す
        int lastElement = deque.removeLast();   // 20を取り出す
        System.out.println("取り出した要素: " + firstElement + ", " + lastElement);
        System.out.println(deque);
    }
}
[10, 20]
取り出した要素: 10, 20
[]

このように、Dequeはスタック、キュー、双方向キューとして利用でき、それぞれの特性を活かしたデータ管理が可能です。

よくある質問

addFirstとofferFirstはどちらを使うべき?

addFirstofferFirstのどちらを使用するかは、プログラムの要件によります。

addFirstは、Dequeが満杯の場合にIllegalStateExceptionをスローします。

一方、offerFirstは、満杯の場合でもfalseを返すため、例外処理を行う必要がありません。

エラーハンドリングを簡素化したい場合や、満杯の状態が頻繁に発生する可能性がある場合は、offerFirstを使用することをお勧めします。

Dequeにnullを追加できる?

ArrayDequeではnull要素を追加することはできませんが、LinkedListではnull要素を追加することが可能です。

したがって、使用する実装クラスによってnullの扱いが異なるため、注意が必要です。

nullを追加する必要がある場合は、LinkedListを選択することを検討してください。

Dequeの要素追加時にスレッドセーフにする方法は?

Dequeはデフォルトではスレッドセーフではありませんが、スレッドセーフにする方法はいくつかあります。

最も一般的な方法は、Collections.synchronizedDequeメソッドを使用して、Dequeをラップすることです。

これにより、スレッドセーフなDequeを作成できます。

以下はその例です。

import java.util.Collections;
import java.util.Deque;
import java.util.LinkedList;
public class App {
    public static void main(String[] args) {
        Deque<Integer> synchronizedDeque = Collections.synchronizedDeque(new LinkedList<>());
        
        // スレッドセーフなDequeに要素を追加
        synchronizedDeque.addFirst(10);
        synchronizedDeque.addLast(20);
        
        // Dequeの内容を表示
        System.out.println(synchronizedDeque);
    }
}

このように、Collections.synchronizedDequeを使用することで、複数のスレッドから安全にDequeにアクセスできるようになります。

まとめ

この記事では、JavaのDequeに要素を追加する方法や、Dequeの実装クラスであるArrayDequeLinkedListの特徴、さらにDequeをスタックやキュー、双方向キューとして利用する方法について詳しく解説しました。

Dequeはその柔軟性から、さまざまなデータ構造として活用できるため、プログラムの要件に応じて適切なメソッドや実装を選択することが重要です。

今後は、実際のプロジェクトでDequeを活用し、効率的なデータ管理を実現してみてください。

当サイトはリンクフリーです。出典元を明記していただければ、ご自由に引用していただいて構いません。

関連カテゴリーから探す

  • Deque (7)
  • 配列 (7)
  • List (18)
  • Stream (1)
  • URLをコピーしました!
目次から探す