반응형
자바에서 Queue
인터페이스는 기본적인 단방향 큐(FIFO)를 정의하는데 사용됩니다. 하지만, 실제로 Queue
대신 Deque
를 사용하여 동일한 동작을 구현해도 성능에 문제가 없습니다. Deque
는 큐와 스택 동작을 모두 지원하므로, Queue
의 모든 기능을 충분히 대체할 수 있습니다.
1. 🌐 Queue
와 Deque
의 차이
1.1 Queue
의 특징
- 단방향 삽입/삭제만 가능하며, FIFO(First In, First Out) 동작을 따릅니다.
- 주요 메서드:
- 삽입:
add(E e)
,offer(E e)
- 삭제:
poll()
,remove()
- 조회:
peek()
,element()
- 삽입:
1.2 Deque
의 특징
- 양방향 삽입/삭제가 가능하지만, 단방향 동작도 구현 가능합니다.
Deque
를 단방향 큐로 사용하면,Queue
의 모든 기능을 대체할 수 있습니다.- 주요 메서드:
- 삽입:
addLast(E e)
(뒤쪽 삽입,Queue
의offer
와 동일) - 삭제:
pollFirst()
(앞쪽 삭제,Queue
의poll
과 동일) - 조회:
peekFirst()
(앞쪽 조회,Queue
의peek
과 동일)
- 삽입:
2. 🎯 Deque
를 사용하여 Queue
동작 구현
코드 예제
import java.util.ArrayDeque;
import java.util.Deque;
public class DequeAsQueueExample {
public static void main(String[] args) {
Deque<Integer> deque = new ArrayDeque<>();
// 큐의 삽입 동작
deque.addLast(10); // Queue의 offer()와 동일
deque.addLast(20);
deque.addLast(30);
// 큐의 삭제 동작
System.out.println(deque.pollFirst()); // 출력: 10 (Queue의 poll()과 동일)
System.out.println(deque.peekFirst()); // 출력: 20 (Queue의 peek()과 동일)
// 남은 요소 출력
System.out.println(deque); // 출력: [20, 30]
}
}
3. 📋 Deque
로 구현할 때 성능 분석
Deque
를 Queue
처럼 사용할 때의 성능은 Queue
구현체와 동일하거나 더 효율적입니다. 특히, ArrayDeque
와 LinkedList
를 사용할 경우의 성능을 비교해 보면 다음과 같은 특징이 있습니다.
3.1 ArrayDeque
의 성능
- 삽입/삭제:
- O(1): 양 끝에서의 삽입/삭제가 빠릅니다.
ArrayDeque
는 내부적으로 배열을 사용하므로 캐시 친화적이고 메모리 접근 속도가 빠릅니다.
- 동적 크기 조정:
- 큐의 크기가 가득 차면 내부 배열을 2배로 늘리는 동작이 발생하지만, 이는 삽입/삭제의 평균 성능에 큰 영향을 미치지 않습니다.
3.2 LinkedList
의 성능
- 삽입/삭제:
- O(1): 양 끝에서 삽입/삭제가 빠릅니다.
- 메모리 오버헤드:
- 각 노드에 추가적인 포인터 메모리를 사용하므로, 배열 기반의
ArrayDeque
보다 메모리를 더 사용합니다.
- 각 노드에 추가적인 포인터 메모리를 사용하므로, 배열 기반의
4. 🔍 왜 Deque
를 사용하는 것이 괜찮은가?
4.1 Queue
대신 Deque
를 사용하는 이유
- 더 많은 기능 지원:
Deque
는 양방향 삽입/삭제 기능을 지원하므로, 더 유연하게 동작할 수 있습니다.- 하지만 단방향 동작만 구현해도 충분히
Queue
를 대체할 수 있습니다.
- 성능 손실 없음:
ArrayDeque
나LinkedList
를 사용하여Deque
를 구현하면,Queue
의 주요 구현체(LinkedList
와ArrayDeque
)와 동일한 성능을 제공합니다.
- 캐시 친화적:
ArrayDeque
는 배열 기반이기 때문에 메모리 접근 속도가 빠르고, 대부분의 상황에서LinkedList
보다 효율적입니다.
5. ⚡ Deque
와 Queue
구현체 비교
구현체 | 동작 방식 | 삽입/삭제 성능 | 중간 접근 성능 | 메모리 사용 | 특징 |
Queue + LinkedList |
연결 리스트 | O(1) | O(n) | 높음 | 동적 크기, 삽입/삭제 효율적 |
Queue + ArrayDeque |
배열 | O(1) | O(n) | 낮음 | 빠른 삽입/삭제, 캐시 친화적 |
Deque + ArrayDeque |
배열 | O(1) | O(n) | 낮음 | 큐와 스택 모두 가능, 양방향 삽입/삭제 지원 |
Deque + LinkedList |
연결 리스트 | O(1) | O(n) | 높음 | 큐와 스택 모두 가능, 유연한 크기 확장 가능 |
6. 💡 요약
Deque
로Queue
구현하기:Deque
를 사용하면 단방향 큐(Queue
)의 동작을 그대로 구현할 수 있습니다.- 예:
addLast
→offer
,pollFirst
→poll
,peekFirst
→peek
.
- 성능 문제 없음:
Deque
를 사용하여 큐를 구현할 경우 성능은 동일하거나 더 효율적입니다.- 특히
ArrayDeque
는 캐시 친화적이고 빠른 삽입/삭제를 제공하므로, 대부분의 경우 추천됩니다.
- 선택 가이드:
- 단순한 큐 작업만 필요하다면
ArrayDeque
를 사용하세요. - 양방향 삽입/삭제가 필요하거나 더 유연한 사용이 필요하면
Deque
인터페이스로 구현하세요. - 정렬이 필요하다면 Queue 인터페이스를 이용한 PriorityQueue 구현체를 사용해야합니다.
- 단순한 큐 작업만 필요하다면
💡 결론적으로,
Deque
는Queue
를 대체할 수 있는 충분히 강력하고 성능이 좋습니다.
반응형
'Java' 카테고리의 다른 글
[JAVA] ArrayList vs LinkedList 완벽 정리 (0) | 2024.12.31 |
---|---|
[JAVA] @Transactional 알아보기 Part.3 #격리(Isolation) (2) | 2024.12.26 |
[JAVA] @Transactional 알아보기 Part.2 #전파(Propagation) (0) | 2024.12.24 |
[JAVA] @Transactional 알아보기 Part.1 #프록시와 트랜잭션 동작 원리 (0) | 2024.12.23 |
[JAVA] Spring 공통 모듈을 패키지화하고 GitHub Packages에 등록하는 방법 (0) | 2024.12.06 |