Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 알고리즘
- 쓰레드
- Java
- linkedmap
- list
- cpu
- os 쓰레드
- Red-Black
- non-blocking
- 배열
- tree
- 코딩테스트
- HashMap
- Lock
- 자바
- OS
- MAP
- 커널모드
- 백준_2559
- 스케줄링
- black-red
- 하드웨어 쓰레드
- 유저 쓰레드
- 유저모드
- 코테
- avl
- 프로그래머스
- set
- 트리
- 백준2559
Archives
변수의 기록
Java Map 컬렉션 정리 – HashMap, LinkedHashMap, TreeMap 본문
먼저 이 글을 쓰게 된 시작 점은 treeMap을 굳이 왜 써야할까? 어떤 상황에서 사용하면 이점이 클까?
그리고 어떤 구조로 관리가 될까?
DB에서 원하는 정렬된 값을 받아와 hashmap에 담으면 되는데? 라는 아주 얇팍한 지식으로 시작됐다....
정리 시작해 보겠습니다.
Java Map 컬렉션 정리 – HashMap, LinkedHashMap, TreeMap
1. Map 컬렉션이란?
Map은 키(key)와 값(value)의 쌍으로 데이터를 저장하는 자료구조다.
중복된 키는 허용하지 않으며, 각 키는 하나의 값만 가질 수 있다.
Java에서 대표적인 Map 구현체는 아래 3가지다.
- HashMap: 기본 해시 기반 Map
- LinkedHashMap: 순서 보장 + 해시 기반 Map
- TreeMap: 정렬 기반 Map
2. Map 계열 자료구조 비교
항목 | HashMap | LinkedHashMap | TreeMap |
내부 구조 | 해시 테이블 (배열 + 체이닝) | 해시 테이블 + 이중 연결 리스트 | Red-Black Tree (이진 탐색 트리) |
순서 보장 | 없음 | 입력 순서 또는 접근 순서 유지 | Key 정렬 순서 유지 |
키 정렬 여부 | 없음 | 없음 | 오름차순 정렬 (Comparator 지정 가능) |
접근/삽입 시간복잡도 | 평균 O(1), 최악 O(log n) | 평균 O(1) (추가 포인터 연산 있음) | O(log n) |
메모리 사용량 | 적음 | 중간 (포인터 추가) | 많음 (트리 포인터 구조) |
용도 | 빠른 조회 중심 | 순서 + 조회 | 정렬 + 범위 검색 |
3. 각 Map의 구조적 차이
3.1 HashMap
- 기본적으로 Node<K,V>[] 배열을 해시 버킷으로 사용
- 키를 hash()로 계산해 배열의 인덱스를 결정하고, 충돌이 발생하면 체이닝 구조 (next) 로 연결
- Java 8 이상에서는 충돌이 많아지면 TreeNode (Red-Black Tree) 로 자동 전환
(버킷 내 요소가 8개 이상, 전체 버킷 수 64 이상 조건)
static class Node<K,V> { final int hash; final K key; V value; Node<K,V> next; }
- 빠른 조회가 목적일 때 사용
- 순서 보장이 필요 없을 때 적합
3.2 LinkedHashMap
- HashMap을 상속해서 구현됨
- 각 Entry에 before, after 포인터를 추가해 입력 순서 또는 접근 순서 유지
- 해시 저장 구조는 그대로 사용하면서, 전체 엔트리를 이중 연결 리스트로 연결
static class LinkedHashMapEntry<K,V> extends HashMap.Node<K,V> { LinkedHashMapEntry<K,V> before, after; }
- put() 시 포인터로 순서 연결
- 순회 시에는 before → after 방향으로 순서 보장됨
3.3 TreeMap
- 내부적으로 Red-Black Tree (이진 탐색 트리) 구조로 key를 저장
- key끼리 Comparable을 구현하거나 Comparator를 전달해야 정렬 가능
- key 값이 들어올 때마다 정렬된 위치에 자동 삽입됨
static final class Entry<K,V> { K key; V value; Entry<K,V> left, right, parent; boolean color; }
- key 기준 정렬이 필요한 경우에 사용
- 범위 기반 탐색 (subMap, tailMap, headMap)에 매우 유용
4. TreeMap의 key 제한?
TreeMap의 key는 정수가 아니어도 된다.
중요한 것은 비교 가능성(Comparable 또는 Comparator) 이다.
사용 가능한 예:
- Integer, String, LocalDate, BigDecimal 등 Comparable 구현체
- 사용자 정의 클래스 + Comparator 전달
TreeMap<String, String> map = new TreeMap<>(); map.put("brc_info", "정보");
5. TreeMap vs ArrayList
항목 | TreeMap | ArrayList |
내부 구조 | Red-Black Tree (이진 트리) | Object[] (배열) |
순서 기준 | key 정렬 기준 | 삽입 순서 (인덱스 순) |
접근 속도 | O(log n) | O(1) (인덱스 기반) |
삽입/삭제 위치 제어 | 정렬 기준에 따라 자동 결정 | 위치 직접 지정 가능 |
용도 | 정렬된 Map이 필요할 때 | 순차 데이터, 반복 처리 |
→ TreeMap은 구조상 연속된 메모리는 아니지만,
정렬 순서를 논리적으로 항상 유지하는 자료구조임.
6. 실무에서 TreeMap/TreeSet이 필요한 경우
TreeMap
- 날짜별 데이터 조회 캐시 (예: 날짜별 매출)
- 등급 기준 혜택 구성 (TreeMap<Integer, String>)
- 실시간 정렬이 필요한 데이터 수집기 (ex. 실시간 로그 분류)
TreeSet
- 중복 제거 + 자동 정렬된 집합 필요
- 실시간 랭킹 처리 (점수 기준 자동 정렬)
- 알파벳순 이름 목록 등 정렬된 리스트
7. 정렬은 화면에서 할까, 서버에서 할까?
- 소규모 데이터 → 프론트(JS)에서 정렬 (array.sort())
- 대규모 데이터 or 페이징 → 백엔드에서 DB 정렬 (ORDER BY)
- 범위 검색/정렬 상태 유지가 중요 → 서버 메모리 내에서 TreeMap 또는 정렬된 리스트로 캐싱
users.sort((a, b) -> a.name.compareTo(b.name)); // JS 정렬 SELECT * FROM user ORDER BY age ASC LIMIT 50; // SQL 정렬 TreeMap<LocalDate, Integer> sales = new TreeMap<>(); // 서버 메모리 정렬
8. 언제 어떤 Map을 써야 할까?
조건 | 추천 Map | 이유 |
빠른 조회 (순서 무관) | HashMap | 평균 O(1) |
입력 순서 기억해야 함 | LinkedHashMap | 연결 포인터로 순서 보존 |
정렬된 key로 순회/탐색 필요 | TreeMap | 정렬 자동 유지, 범위 검색 용이 |
key 중복 없이 정렬만 필요 | TreeSet | Set 특성 + 정렬 |
마무리
정렬이 필요한 경우, 단순히 ORDER BY로 해결할 수 있지만
정렬 상태를 메모리 내에서 유지하거나, 범위 탐색이 자주 발생한다면
TreeMap 또는 TreeSet은 매우 유용한 선택이다.
반면, 빠른 접근만 필요하고 정렬이 불필요하다면 HashMap이 여전히 가장 강력한 기본 선택이다.
'자바 > 자바' 카테고리의 다른 글
(Java) Set의 구조와 활용 - ADT 관점으로 이해 (0) | 2025.04.23 |
---|---|
(Java) Map 구조 정리 - ADT 관점에서의 이해 (****별 다섯개****) (0) | 2025.04.23 |
(java) 기본 배열(Array), 동적 배열(Dynamic Array), 연관 배열(Associative Array)의 개념과 내부 동작 원리를 설명 (0) | 2025.04.22 |
자바 스레드 덤프(Thread Dump) 분석 방법 (0) | 2025.04.13 |
(java) 인터페이스 왜 쓸까? (0) | 2025.03.27 |