Java ArrayDeque 마스터: 완벽 가이드 & 스택 구현
Java ArrayDeque
ArrayDeque 클래스, 메서드, 실전 예제(스택으로 사용하는 법 포함)를 설명합니다.
Java에서 ArrayDeque는 크기 조절 가능 배열로 뒷받침되는 큐와 덱 자료구조를 구현합니다.
ArrayDeque가 구현하는 인터페이스
ArrayDeque 클래스는 다음 인터페이스를 구현합니다:
- Java Queue 인터페이스
- Java Deque 인터페이스
ArrayDeque 생성하기
패키지 임포트:
import java.util.ArrayDeque;
타입 지정된 덱 인스턴스화:
ArrayDeque<Type> deque = new ArrayDeque<>();
예제:
// String 덱
ArrayDeque<String> animals = new ArrayDeque<>();
// Integer 덱
ArrayDeque<Integer> ages = new ArrayDeque<>();
핵심 ArrayDeque 메서드
요소 삽입하기
1. add(), addFirst(), addLast() 사용
add(E e) – e를 꼬리에 추가
addFirst(E e) – e를 머리에 삽입
addLast(E e) – add()와 동일
주의: 덱이 가득 차면 IllegalStateException 발생
ArrayDeque<String> animals = new ArrayDeque<>();
animals.add("Dog");
animals.addFirst("Cat");
animals.addLast("Horse");
System.out.println("ArrayDeque: " + animals);
출력
ArrayDeque: [Cat, Dog, Horse]
2. offer(), offerFirst(), offerLast() 사용
offer(E e) – e를 꼬리에 추가, 성공 시 true 반환
offerFirst(E e) – e를 머리에 삽입
offerLast(E e) – offer()와 동일
주의: 덱이 가득 차면 false 반환
ArrayDeque<String> animals = new ArrayDeque<>();
animals.offer("Dog");
animals.offerFirst("Cat");
animals.offerLast("Horse");
System.out.println("ArrayDeque: " + animals);
출력
ArrayDeque: [Cat, Dog, Horse]
요소 접근하기
1. getFirst()와 getLast()
getFirst() – 머리 요소 반환
getLast() – 꼬리 요소 반환
주의: 덱이 비어있으면 NoSuchElementException 발생
ArrayDeque<String> animals = new ArrayDeque<>();
animals.add("Dog");
animals.add("Cat");
animals.add("Horse");
System.out.println("ArrayDeque: " + animals);
System.out.println("First Element: " + animals.getFirst());
System.out.println("Last Element: " + animals.getLast());
출력
ArrayDeque: [Dog, Cat, Horse] First Element: Dog Last Element: Horse
2. peek(), peekFirst(), peekLast()
peek() – 제거 없이 머리 조회
peekFirst() – peek()의 동의어
peekLast() – 꼬리 조회
ArrayDeque<String> animals = new ArrayDeque<>();
animals.add("Dog");
animals.add("Cat");
animals.add("Horse");
System.out.println("ArrayDeque: " + animals);
System.out.println("Head Element: " + animals.peek());
System.out.println("First Element: " + animals.peekFirst());
System.out.println("Last Element: " + animals.peekLast());
출력
ArrayDeque: [Dog, Cat, Horse] Head Element: Dog First Element: Dog Last Element: Horse
주의: 덱이 비어있으면 peek() 계열은 예외 대신 null 반환
요소 제거하기
1. remove(), removeFirst(), removeLast()
remove() – 머리 제거 및 반환
removeFirst() – remove()와 동일
removeLast() – 꼬리 제거 및 반환
remove(Object o) – o의 첫 번째 출현 제거(존재 시)
주의: 덱이 비어있거나 remove(o)가 o를 못 찾으면 NoSuchElementException 발생
ArrayDeque<String> animals = new ArrayDeque<>();
animals.add("Dog");
animals.add("Cat");
animals.add("Cow");
animals.add("Horse");
System.out.println("ArrayDeque: " + animals);
System.out.println("Removed Element: " + animals.remove());
System.out.println("New ArrayDeque: " + animals);
System.out.println("Removed First Element: " + animals.removeFirst());
System.out.println("Removed Last Element: " + animals.removeLast());
출력
ArrayDeque: [Dog, Cat, Cow, Horse] Removed Element: Dog New ArrayDeque: [Cat, Cow, Horse] Removed First Element: Cat Removed Last Element: Horse
2. poll(), pollFirst(), pollLast()
poll() – 머리 제거 및 반환, 비어있으면 null
pollFirst() – poll()의 동의어
pollLast() – 꼬리 제거 및 반환
ArrayDeque<String> animals = new ArrayDeque<>();
animals.add("Dog");
animals.add("Cat");
animals.add("Cow");
animals.add("Horse");
System.out.println("ArrayDeque: " + animals);
System.out.println("Removed Element: " + animals.poll());
System.out.println("New ArrayDeque: " + animals);
System.out.println("Removed First Element: " + animals.pollFirst());
System.out.println("Removed Last Element: " + animals.pollLast());
출력
ArrayDeque: [Dog, Cat, Cow, Horse] Removed Element: Dog New ArrayDeque: [Cat, Cow, Horse] Removed First Element: Cat Removed Last Element: Horse
3. clear()
덱 전체 비우기
ArrayDeque<String> animals = new ArrayDeque<>();
animals.add("Dog");
animals.add("Cat");
animals.add("Horse");
System.out.println("ArrayDeque: " + animals);
animals.clear();
System.out.println("New ArrayDeque: " + animals);
출력
ArrayDeque: [Dog, Cat, Horse] New ArrayDeque: []
ArrayDeque 순회하기
iterator() – 정방향 이터레이터
descendingIterator() – 역방향 이터레이터
ArrayDeque<String> animals = new ArrayDeque<>();
animals.add("Dog");
animals.add("Cat");
animals.add("Horse");
System.out.print("ArrayDeque: ");
Iterator<String> it = animals.iterator();
while(it.hasNext()) {
System.out.print(it.next() + ", ");
}
System.out.print("\nArrayDeque in reverse order: ");
Iterator<String> rev = animals.descendingIterator();
while(rev.hasNext()) {
System.out.print(rev.next() + ", ");
}
출력
ArrayDeque: [Dog, Cat, Horse] ArrayDeque in reverse order: [Horse, Cat, Dog]
기타 주요 메서드
| 메서드 | 설명 |
element() | 머리 요소 조회(제거 안 함) |
contains(Object o) | o 존재 여부 확인, 발견 시 true |
size() | 덱의 요소 수 |
toArray() | 덱을 배열로 변환 |
clone() | 덱의 얕은 복사본 생성 |
ArrayDeque를 스택으로 사용하기
LIFO 동작에는 Stack보다 ArrayDeque가 선호됩니다. 더 나은 성능과 레거시 동기화 오버헤드가 없기 때문입니다.
스택 스타일 메서드:
push(E e) – 머리에 추가
peek() – 제거 없이 상단 요소 조회
pop() – 상단 요소 제거 및 반환
ArrayDeque<String> stack = new ArrayDeque<>();
stack.push("Dog");
stack.push("Cat");
stack.push("Horse");
System.out.println("Stack: " + stack);
System.out.println("Accessed Element: " + stack.peek());
System.out.println("Removed Element: " + stack.pop());
출력
Stack: [Horse, Cat, Dog] Accessed Element: Horse Removed Element: Horse
ArrayDeque vs LinkedList
둘 다 Deque를 구현하지만 차이가 있습니다:
LinkedList는 null 요소 허용, ArrayDeque는 불허
- LinkedList 노드는 포인터 저장으로 메모리 더 소비
- 큐/덱 워크로드에서
ArrayDeque가 일반적으로 LinkedList보다 우수