[Java] ArrayDeque
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) 방식.
- head 와 tail 인덱스를 따로 관리
- 배열의 끝에 도달하면 다시 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, addLast | amortized O(1) |
removeFirst, removeLast | O(1) |
peek*, getFirst, getLast | O(1) |
contains, remove(Object) | O(n) |
| 임의 인덱스 접근 | 불가 (List 가 아니므로) |
amortized 인 이유는 가득 찼을 때 2 배 grow + copy 비용 때문. 평균은 O(1).
LinkedList vs ArrayDeque
| 항목 | LinkedList | ArrayDeque |
|---|---|---|
| 백킹 | linked nodes | 원형 배열 |
| 메모리 / 원소 | 노드 헤더 + 두 포인터 (~32B) | 슬롯 1 개 (4-8B) |
| 캐시 친화 | ✗ | ✓ |
| addFirst / addLast | O(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) 순서로 원소를 관리하는 추상 자료구조입니다. (또는 ), (또는 ), 세 연산만 제공하며, 가장 먼저 …
💬 댓글