본문으로 건너뛰기
김신건의 로그

[Java] ArrayDeque

· 수정 · 📖 약 1분 · 366자/단어 #java #collection #deque #queue #stack #array
ArrayDeque, java.util.ArrayDeque, Java ArrayDeque, 어레이덱, circular array deque

정의

java.util.ArrayDeque<E>원형 배열 (circular buffer) 기반의 Deque 구현. JDK 1.6 도입.

Stack 으로 쓰면 java.util.Stack 보다 빠르고, Queue 로 쓰면 LinkedList 보다 빠르다. Stack / Queue / Deque 가 필요할 때 거의 항상 첫 번째 선택.

시각화

내부 구조

public class ArrayDeque<E> extends AbstractCollection<E>
    implements Deque<E>, Cloneable, Serializable {

    transient Object[] elements;       // 백킹 배열
    transient int head;                // head 인덱스
    transient int tail;                // tail 인덱스 (next slot)
}

원형 배열 (circular array) 방식.

  • headtail 인덱스를 따로 관리
  • 배열의 끝에 도달하면 다시 0 으로 (modular arithmetic)
  • 가득 차면 2 배로 grow
초기 (size 8):  [_ _ _ _ _ _ _ _]
                 ↑head=tail=0

addLast: a, b, c
        [a b c _ _ _ _ _]
         ↑head    ↑tail=3

addFirst: x
        [a b c _ _ _ _ x]
                       ↑head=7  tail=3

수정된 인덱스 = (i + length) % length

복잡도

작업시간
addFirst, addLastamortized O(1)
removeFirst, removeLastO(1)
peek*, getFirst, getLastO(1)
contains, remove(Object)O(n)
임의 인덱스 접근불가 (List 가 아니므로)

amortized 인 이유는 가득 찼을 때 2 배 grow + copy 비용 때문. 평균은 O(1).

LinkedList vs ArrayDeque

항목LinkedListArrayDeque
백킹linked nodes원형 배열
메모리 / 원소노드 헤더 + 두 포인터 (~32B)슬롯 1 개 (4-8B)
캐시 친화
addFirst / addLastO(1)amortized O(1)
null 허용
List 가능✓ (인덱스 O(n))
Deque 가능
실측 속도느림빠름

null 거부와 List 미구현이 단점이지만, 그 외에는 모든 면에서 LinkedList 보다 우월.

Stack 사용 예

Deque<Integer> stack = new ArrayDeque<>();
stack.push(1);              // head 쪽에 push
stack.push(2);
stack.push(3);
stack.peek();               // 3
stack.pop();                // 3

Deque<E> stack = new ArrayDeque<>() 패턴이 [[java] Vector]] 기반 Stack<E> 보다 두세 배 빠르다.

Queue 사용 예

Queue<Task> queue = new ArrayDeque<>();
queue.offer(task1);
queue.offer(task2);
Task t = queue.poll();      // task1 (FIFO)

함정

1. null 비허용

Deque<String> dq = new ArrayDeque<>();
dq.add(null);    // NullPointerException

이유: poll/peek 이 null 을 “비어 있음” 신호로 쓰는 의미와 충돌.

2. thread-safe 가 아님

ConcurrentLinkedDeque 또는 LinkedBlockingDeque 사용.

3. iterator 는 fail-fast iterator

순회 중 수정 시 CME.

참고

이 글의 용어 (8개)
[Java] Collectionjava
정의 는 그룹으로 묶인 객체들을 표현하는 최상위 인터페이스. JCF (Java Collections Framework) 의 입구이자, / / / 모두 이를 확장한다. 자체는 직접…
[Java] ConcurrentLinkedDequejava
정의 는 lock-free . 의 양방향 버전. JDK 1.7 추가. 양 끝 모두에서 add/remove 가능, 모든 연산이 CAS 기반. 내부 구조 이중 연결 리스트 ( , 모…
[Java] Fail-Fast Iteratorjava
정의 Fail-Fast Iterator 는 순회 도중 컬렉션의 구조가 변경되면 즉시 을 던지는 iterator. , , 등 대부분의 컬렉션의 iterator 가 이 방식. 목적은…
[Java] Iterablejava
정의 는 루프로 순회 가능한 모든 타입의 최상위 인터페이스. 단 하나의 추상 메서드, 를 정의한다. 인터페이스가 을 extends 하므로 , , , 등 모든 컬렉션이 자동으로 대…
[Java] LinkedListjava
정의 는 양방향 연결 리스트 (doubly linked list) 로 구현된 이자 . 각 원소는 와 포인터를 가진 노드로 보관된다. 와 같은 List 이지만, 메모리 레이아웃과 …
[Java] Objectjava
정의 는 Java 의 모든 클래스의 최상위 부모 (root) 클래스. 가 명시되지 않은 클래스는 컴파일러가 자동으로 를 붙인다. 인터페이스는 클래스가 아니라 를 직접 상속하지는 …
덱 (Deque)algorithm
정의 Deque (덱, double-ended queue) 는 양쪽 끝에서 O(1) push/pop 이 가능한 선형 자료구조. 큐 + 스택의 일반화. 내부 구현은 대개 chunk…
큐 (Queue)algorithm
정의 큐 (Queue) 는 FIFO (First In, First Out) 순서로 원소를 관리하는 추상 자료구조입니다. (또는 ), (또는 ), 세 연산만 제공하며, 가장 먼저 …

이 개념을 다룬 위키 페이지 (3)

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기