| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 자바
- HashMap
- 코딩인터뷰
- 가비지컬렉션
- 메모리관리
- 개발공부
- Java
- 자바프로그래밍
- JVM
- 멀티스레드
- 코딩테스트준비
- 개발자취업
- 코딩테스트
- 자료구조
- 개발자팁
- 예외처리
- 정렬
- 프로그래머스
- 알고리즘공부
- 프로그래밍기초
- 코딩공부
- 자바기초
- 자바공부
- 코딩테스트팁
- 알고리즘
- 객체지향
- 클린코드
- 백준
- 자바개발
- 파이썬
- Today
- Total
코드 한 줄의 기록
Java Queue, Deque, PriorityQueue 완벽 가이드 본문
코딩 테스트를 준비하다 보면 Queue 관련 자료구조를 정말 많이 사용하게 됩니다. 특히 BFS 알고리즘이나 우선순위 처리 같은 문제에서 필수적이죠. 저도 처음엔 이 세 가지가 뭐가 다른지 헷갈렸는데, 하나씩 공부하면서 정리해보니 확실히 이해가 되더라고요. 오늘은 제가 공부한 내용을 바탕으로 Queue, Deque, PriorityQueue의 사용 패턴을 같이 살펴보려고 합니다.
Queue 인터페이스 기본 개념
Queue는 FIFO(First-In-First-Out) 방식으로 동작하는 자료구조입니다. 쉽게 말해 먼저 들어간 데이터가 먼저 나오는 구조죠. 은행 창구에서 번호표를 뽑고 기다리는 것과 비슷하다고 생각하면 됩니다.
Java에서 Queue는 인터페이스로 제공되기 때문에 직접 인스턴스를 만들 수 없습니다. 대신 LinkedList나 PriorityQueue 같은 구현 클래스를 사용해야 합니다.
Queue<Integer> queue = new LinkedList<>();
queue.offer(1);
queue.offer(2);
queue.offer(3);
System.out.println(queue.poll()); // 1 출력
Queue의 핵심 메서드
Queue 인터페이스는 크게 두 가지 스타일의 메서드를 제공합니다.
- 예외를 던지는 메서드: add(), remove(), element()
- 특수 값을 반환하는 메서드: offer(), poll(), peek()
실무에서는 offer, poll, peek를 더 자주 사용합니다. 예외를 던지는 대신 null이나 false를 반환하기 때문이죠.
Queue<String> queue = new LinkedList<>();
queue.offer("first");
queue.offer("second");
System.out.println(queue.poll()); // first
System.out.println(queue.remove()); // second
System.out.println(queue.poll()); // null
LinkedList를 Queue로 사용하기
LinkedList는 Queue 인터페이스를 구현하고 있어서 큐로 사용할 수 있습니다. 하지만 일반적인 큐 용도로는 ArrayDeque가 더 효율적이라고 알려져 있습니다.
Queue<Integer> linkedQueue = new LinkedList<>();
linkedQueue.offer(10);
linkedQueue.offer(20);
linkedQueue.offer(30);
while (!linkedQueue.isEmpty()) {
System.out.println(linkedQueue.poll());
}
Deque로 더 유연하게 작업하기
Deque는 Double Ended Queue의 약자로, 양쪽 끝에서 데이터를 추가하거나 제거할 수 있는 자료구조입니다. 스택과 큐 두 가지 역할을 모두 수행할 수 있습니다.
Deque의 주요 메서드
- 앞쪽: addFirst(), offerFirst(), removeFirst(), pollFirst(), peekFirst()
- 뒤쪽: addLast(), offerLast(), removeLast(), pollLast(), peekLast()
Deque<String> deque = new ArrayDeque<>();
deque.addFirst("첫번째");
deque.addLast("마지막");
deque.addFirst("새로운 첫번째");
System.out.println(deque.peekFirst());
System.out.println(deque.peekLast());
Deque를 Stack처럼 사용하기
Deque는 Stack 자료구조로도 사용할 수 있습니다. Java에서는 레거시 Stack 클래스 대신 Deque를 권장합니다.
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(stack.pop()); // 3
ArrayDeque vs LinkedList 성능 비교
| 구현체 | 특징 |
| ArrayDeque | 빠른 속도, 메모리 효율 좋음, null 허용하지 않음 |
| LinkedList | 메모리 많이 사용, null 허용, 중간 삽입 유리 |
Deque 활용 예시: 슬라이딩 윈도우 최댓값
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> deque = new ArrayDeque<>();
int[] result = new int[nums.length - k + 1];
for (int i = 0; i < nums.length; i++) {
while (!deque.isEmpty() && deque.peekFirst() <= i - k)
deque.pollFirst();
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i])
deque.pollLast();
deque.offerLast(i);
if (i >= k - 1)
result[i - k + 1] = nums[deque.peekFirst()];
}
return result;
}
PriorityQueue로 우선순위 처리하기
PriorityQueue는 내부적으로 힙(Heap) 구조를 사용하는 우선순위 큐입니다. 값이 작은 요소부터 우선적으로 반환됩니다.
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(5);
pq.offer(2);
pq.offer(8);
pq.offer(1);
System.out.println(pq.peek()); // 1
커스텀 Comparator 사용하기
class Task {
String name;
int priority;
Task(String name, int priority) {
this.name = name;
this.priority = priority;
}
}
PriorityQueue<Task> taskQueue = new PriorityQueue<>(
(t1, t2) -> t2.priority - t1.priority
);
taskQueue.offer(new Task("작업1", 3));
taskQueue.offer(new Task("작업2", 1));
while (!taskQueue.isEmpty()) {
Task task = taskQueue.poll();
System.out.println(task.name + " : " + task.priority);
}
PriorityQueue 활용 예제: K번째 큰 수
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int n : nums) {
pq.offer(n);
if (pq.size() > k) pq.poll();
}
return pq.peek();
}
활용 패턴 정리
- Queue: BFS, 순차적 작업처리
- Deque: 스택/큐 혼합 문제, 슬라이딩 윈도우
- PriorityQueue: 다익스트라, 우선순위 작업 처리, K번째 값
Queue, Deque, PriorityQueue는 자바 컬렉션 프레임워크에서 자주 쓰이지만 각각의 특성과 시간복잡도를 이해하면 훨씬 더 효율적으로 사용할 수 있습니다. 이 세 가지를 자유자재로 다룰 수 있게 되면 코딩 테스트 문제 해결력이 확실히 올라갑니다.
Java Map 완전 정복: HashMap, LinkedHashMap, TreeMap 비교와 키 설계 핵심 가이드
Java 개발을 하다 보면 Map은 정말 자주 사용하게 되는 자료구조입니다. 특히 HashMap은 거의 매일 쓰게 되는데요, 막상 "왜 HashMap을 쓰는 거야?"라고 물어보면 명확하게 대답하기 어려운 경우가 많습
byteandbit.tistory.com
'JAVA' 카테고리의 다른 글
| Java Iterator와 Fail-Fast, 컬렉션 수정 시 주의할 점들 (0) | 2025.10.27 |
|---|---|
| Java Comparable과 Comparator 완벽 가이드 - 정렬 전략 완전 정복 (0) | 2025.10.27 |
| Java Map 완전 정복: HashMap, LinkedHashMap, TreeMap 비교와 키 설계 핵심 가이드 (0) | 2025.10.26 |
| Java HashSet, TreeSet, LinkedHashSet 완벽 정리 - 특성과 정렬 방법 (0) | 2025.10.26 |
| ArrayList vs LinkedList 언제 어떤 걸 써야 할까? (0) | 2025.10.25 |