이제 util 차례다. 여기 있는 메서드를 잘 몰라서, 내가 구현해서 사용한적도 있다. 코테 때는 시간이 얼마나 있을지 모르니, 잘 숙지해주자!
import java.util.*;
임포트는 필수!
List
한 줄 요약: "순서가 있는 데이터의 집합". 가장 기본적이고 많이 사용하는 자료구조입니다.
언제 사용하나?: 데이터를 들어온 순서대로 저장하고, 인덱스를 통해 특정 위치의 데이터에 접근해야 할 때.
List<Integer> list = new ArrayList<>(); // 가장 일반적인 형태
| 메서드 | 설명 | 예시 |
| add(value) | 리스트의 맨 끝에 데이터를 추가합니다. | list.add(10); |
| add(index, value) | 특정 인덱스에 데이터를 삽입합니다. | list.add(0, 5); |
| get(index) | 특정 인덱스의 데이터를 조회합니다. | int num = list.get(0); |
| set(index, value) | 특정 인덱스의 데이터를 교체합니다. | list.set(0, 1); |
| remove(index) | 특정 인덱스의 데이터를 삭제합니다. | list.remove(0); |
| size() | 리스트에 저장된 데이터의 개수를 반환합니다. | int size = list.size(); |
| isEmpty() | 리스트가 비어있는지 확인합니다. (true/false) | boolean empty = list.isEmpty(); |
| clear() | 리스트의 모든 요소를 삭제합니다. | list.clear(); |
파이썬의 리스트처럼 사용하면 될 것 같다.
참고로 add를 통해 값을 삽입하면, 그 뒤에 있는 인덱스는 다 한칸씩 뒤로 밀린다.
Map
한 줄 요약: "Key-Value 쌍으로 데이터를 저장하는 사전". Key를 통해 Value를 매우 빠르게 찾을 수 있습니다. (평균 시간복잡도 O(1))
언제 사용하나?: 데이터의 등장 횟수 카운팅, 특정 ID와 객체를 매핑하는 등 빠른 탐색이 필요할 때.
Map<String, Integer> map = new HashMap<>(); // Key: String, Value: Integer
Map<Integer, String> map = new HashMap<>(); // Key: Integer, Value: String
| 메서드 | 설명 | 예시 |
| put(key, value) | Key와 Value를 쌍으로 맵에 저장합니다. | map.put("사과", 1000); |
| get(key) | Key에 해당하는 Value를 조회합니다. 없으면 null 반환. | int price = map.get("사과"); |
| getOrDefault(key, defaultValue) | (강력 추천) Key에 해당하는 Value를 조회하되, 없으면 defaultValue를 반환합니다. null 체크를 줄여 코드가 깔끔해집니다. | int count = map.getOrDefault("배", 0); |
| containsKey(key) | 특정 Key가 맵에 존재하는지 확인합니다. (true/false) | boolean hasApple = map.containsKey("사과"); |
| remove(key) | 특정 Key에 해당하는 데이터를 삭제합니다. | map.remove("사과"); |
| size() | 맵에 저장된 데이터 쌍의 개수를 반환합니다. | int size = map.size(); |
| isEmpty() | 맵이 비어있는지 확인합니다. (true/false) | boolean empty = map.isEmpty(); |
| clear() | 맵의 모든 요소를 삭제합니다. | map.clear() |
Set
한 줄 요약: "중복을 허용하지 않는 데이터의 집합". 순서를 보장하지 않습니다.
언제 사용하나?: 배열/리스트의 중복 제거, 특정 데이터의 존재 여부만 빠르게 확인하고 싶을 때.
Set<Integer> set = new HashSet<>();
| 메서드 | 설명 | 예시 |
| add(value) | Set에 데이터를 추가합니다. 이미 존재하는 값이면 무시됩니다. | set.add(10); |
| contains(value) | 특정 데이터가 Set에 존재하는지 확인합니다. (true/false) | boolean has10 = set.contains(10); |
| remove(value) | Set에서 특정 데이터를 삭제합니다. | set.remove(10); |
| size() | Set에 저장된 데이터의 개수를 반환합니다. | int size = set.size(); |
| isEmpty() | Set이 비어있는지 확인합니다. (true/false) | boolean empty = set.isEmpty(); |
| clear() | Set의 모든 요소를 삭제합니다. | set.clear() |
Stack
한 줄 요약: 후입선출(LIFO: Last-In, First-Out). 가장 마지막에 넣은 데이터가 가장 먼저 나옵니다.
언제 사용하나?: 깊이 우선 탐색(DFS), 괄호 짝 맞추기, 재귀적 동작을 반복문으로 구현할 때 사용합니다.
// (추천) 성능이 좋은 ArrayDeque를 Deque 인터페이스로 사용
Deque<Integer> stack = new ArrayDeque<>();
// 참고: 오래된 Stack 클래스도 있지만, 성능상 ArrayDeque 사용이 권장됩니다.
// Stack<Integer> stack = new Stack<>();
| 메서드 | 설명 | 예시 |
| push(value) | 스택의 맨 위에 데이터를 추가합니다. | stack.push(10); |
| pop() | 스택의 맨 위 데이터를 꺼내고 삭제합니다. (비어있으면 에러 발생) | int top = stack.pop(); |
| peek() | 스택의 맨 위 데이터를 확인만 합니다. (삭제 X) | int top = stack.peek(); |
| size() | 스택에 저장된 데이터의 개수를 반환합니다. | int size = stack.size(); |
| isEmpty() | 스택이 비어있는지 확인합니다. (true/false) | boolean empty = stack.isEmpty(); |
| clear() | 스택의 모든 요소를 삭제합니다. | stack.clear(); |
Queue
한 줄 요약: 선입선출(FIFO: First-In, First-Out). 가장 먼저 넣은 데이터가 가장 먼저 나옵니다. (은행 대기줄)
언제 사용하나?: 너비 우선 탐색(BFS) 알고리즘의 핵심 자료구조이며, 작업의 순서가 중요할 때 사용합니다.
// Queue 인터페이스는 보통 LinkedList로 구현하여 사용합니다.
Queue<Integer> queue = new LinkedList<>();
| 메서드 | 설명 | 예시 |
| offer(value) | 큐의 맨 끝에 데이터를 추가합니다. (add와 달리 실패 시 false 반환) | queue.offer(10); |
| poll() | 큐의 맨 앞에서 데이터를 꺼내고 삭제합니다. (remove와 달리 큐가 비어있으면 null 반환) | int front = queue.poll(); |
| peek() | 큐의 맨 앞 데이터를 확인만 합니다. (삭제 X) (element와 달리 큐가 비어있으면 null 반환) | int front = queue.peek(); |
| size() | 큐에 저장된 데이터의 개수를 반환합니다. | int size = queue.size(); |
| isEmpty() | 큐가 비어있는지 확인합니다. (true/false) | boolean empty = queue.isEmpty(); |
| clear() | 큐의 모든 요소를 삭제합니다. | queue.clear(); |
이건 Queue 에서 같은 동작을 하는 메서드인데, 실패시 다른 값을 반환해서 분류한 것이다.
| 기능 | 안전한 버전 | 실패 시 반환 값 | 예외 발생 버전 | 실패 시 동작 |
| 데이터 추가 | offer(e) | false (큐가 꽉 찼을 경우) | add(e) | IllegalStateException 발생 |
| 데이터 꺼내기 (삭제 O) | poll() | null (큐가 비어있을 경우) | remove() | NoSuchElementException 발생 |
| 데이터 확인 (삭제 X) | peek() | null (큐가 비어있을 경우) | element() | NoSuchElementException 발생 |
Heap (PriorityQueue)
한 줄 요약: 우선순위가 가장 높은 데이터가 먼저 나오는 똑똑한 큐. (응급실 시스템)
언제 사용하나?: 단순히 들어온 순서가 아니라, 가장 작은 값 또는 가장 큰 값을 계속해서 빠르게 뽑아내야 할 때 사용합니다. (e.g., 다익스트라 최단 경로, 가장 맵지 않은 음식 섞기)
// 기본은 가장 작은 값이 먼저 나오는 '최소 힙(Min-Heap)'
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
// 가장 큰 값이 먼저 나오는 '최대 힙(Max-Heap)'으로 만들려면
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
| 메서드 | 설명 | 예시 |
| offer(value) | 우선순위 큐에 데이터를 추가합니다. 데이터는 자신의 우선순위에 맞는 위치를 자동으로 찾아갑니다. | minHeap.offer(10); |
| poll() | 우선순위가 가장 높은 데이터를 꺼내고 삭제합니다. (최소 힙에서는 가장 작은 값) (큐가 비어있으면 null 반환) | int smallest = minHeap.poll(); |
| peek() | 우선순위가 가장 높은 데이터를 확인만 합니다. (삭제 X) (큐가 비어있으면 null 반환) | int smallest = minHeap.peek(); |
| size() | 큐에 저장된 데이터의 개수를 반환합니다. | int size = minHeap.size(); |
| isEmpty() | 큐가 비어있는지 확인합니다. (true/false) | boolean empty = minHeap.isEmpty(); |
| clear() | 큐의 모든 요소를 삭제합니다. | minHeap.clear(); |
사용법은 위에 큐와 메서드가 일치하는 것 같다.
예전에 이거 몰라서 treeset? 같은거 사용했던 것 같다.
후기
생각보다 너무 많다. 그래도 알고리즘 문제 풀다보면 자연스럽게 외워질 것 같다.
다음에는 map 에서 key와 value를 가져오는 방법을 정리해볼까 한다.
댓글