도입
자바를 공부할 때 가장 많이 헷갈리는 주제 중 하나가 바로 List, Set, Map의 차이입니다.
셋 다 데이터를 저장하는 도구처럼 보이지만, 실제로는 무엇을 기준으로 데이터를 다루는지가 완전히 다릅니다.
어떤 경우에는 순서가 중요하고, 어떤 경우에는 중복 제거가 중요하며, 어떤 경우에는 특정 키로 빠르게 찾는 것이 핵심입니다.
그래서 세 가지 구조를 “문법 차이”가 아니라 문제 해결 방식의 차이로 이해해야 실무에서도 헷갈리지 않습니다.
정의
| 구조 | 핵심 개념 | 저장 방식 |
|---|---|---|
| List | 순서 | 값을 순차적으로 저장 |
| Set | 중복 제거 | 중복 없는 값 저장 |
| Map | 키 기반 조회 | 키-값 쌍 저장 |
여기서 중요한 점은 Map은 List/Set과 같은 “값 컬렉션” 계열과 결이 조금 다르다는 것입니다. List와 Set은 값 그 자체를 저장하지만, Map은 값을 찾기 위한 키 관계를 함께 저장합니다.
핵심 차이
| 항목 | List | Set | Map |
|---|---|---|---|
| 저장 대상 | 값 | 값 | 키와 값 |
| 순서 | 있음 | 구현체에 따라 다름 | 구현체에 따라 다름 |
| 중복 | 허용 | 불가 | 키 중복 불가, 값 중복 가능 |
| 접근 방식 | 인덱스 | 존재 여부 중심 | 키로 조회 |
| 대표 용도 | 순서 있는 데이터 | 중복 제거, 포함 여부 확인 | 매핑, 인덱싱, 집계 |
List
List는 데이터를 저장한 순서를 유지하며, 각 원소에 인덱스로 접근할 수 있습니다. 따라서 “첫 번째”, “두 번째”, “마지막”처럼 위치 개념이 중요한 문제에 잘 맞습니다.
- 게시글 목록, 댓글 목록
- 입력 순서를 그대로 유지해야 하는 데이터
- 인덱스로 특정 위치를 조회해야 하는 경우
- 중복 값이 자연스럽게 허용되는 경우
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("A");
System.out.println(list.get(0)); // A
Set
Set은 같은 값을 두 번 넣어도 하나만 유지합니다. 그래서 “중복 제거”와 “존재 여부 확인”이 핵심인 상황에서 매우 강력합니다.
- 중복된 값을 제거해야 하는 경우
- 이미 본 값인지 빠르게 판단해야 하는 경우
- 회원 ID, 태그, 방문 기록처럼 유일성 중심 데이터
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("A");
System.out.println(set.size()); // 2
Map
Map은 값을 그냥 저장하는 구조가 아니라, 특정 키를 기준으로 값을 꺼내는 구조입니다. 따라서 “이름 → 점수”, “ID → 회원정보”, “코드 → 가격” 같은 매핑 문제에 가장 자연스럽습니다.
Map<String, Integer> map = new HashMap<>();
map.put("kim", 90);
map.put("lee", 80);
System.out.println(map.get("kim")); // 90
Map은 List와 Set처럼 Collection 인터페이스 계열로 자주 묶여 이야기되지만, 엄밀히 보면 키-값 구조라는 점에서 성격이 다릅니다.
대표 구현체
| 분류 | 구현체 | 특징 |
|---|---|---|
| List | ArrayList | 조회가 빠르고 가장 많이 사용됨 |
| List | LinkedList | 연결 구조 기반, 큐/덱 용도로도 사용 |
| Set | HashSet | 중복 제거와 빠른 존재 확인에 적합 |
| Set | LinkedHashSet | 삽입 순서 유지 |
| Set | TreeSet | 자동 정렬 |
| Map | HashMap | 가장 일반적인 기본 Map |
| Map | LinkedHashMap | 삽입 순서 유지 |
| Map | TreeMap | 키 자동 정렬 |
시간 복잡도 관점
| 구조 | 강한 연산 | 약한 연산 |
|---|---|---|
| ArrayList | 인덱스 조회 | 중간 삽입/삭제 |
| HashSet | 포함 여부 확인 | 인덱스 기반 접근 불가 |
| HashMap | 키 기반 조회 | 순서 기반 처리 |
언제 무엇을 쓰나
- 순서와 인덱스가 중요하다 → List
- 중복 제거가 핵심이다 → Set
- 특정 기준으로 값을 빠르게 찾고 싶다 → Map
- 순서도 유지하고 싶다 → ArrayList / LinkedHashSet / LinkedHashMap 등 구현체 선택
- 정렬도 필요하다 → TreeSet / TreeMap 고려
실전 예시
- 가입 순서대로 보여주기 → List
- 중복 가입 이름 제거 → Set
- ID로 회원 정보 찾기 → Map
- 입력 순서대로 저장 → List
- 중복 단어 제거 → Set
- 단어별 등장 횟수 저장 → Map
자주 하는 오해
- 오해 1 : Set은 그냥 List에서 중복만 막은 것 → 아니다. 존재 여부 판단 중심이라는 의미가 더 크다.
- 오해 2 : Map도 그냥 값 저장 구조다 → 아니다. 키로 값을 찾는 매핑 구조다.
- 오해 3 : Hash 구조는 항상 순서가 없다 → LinkedHash 계열은 순서를 유지한다.
- 오해 4 : 중복 제거가 필요하면 무조건 Set → “몇 번 등장했는가”가 중요하면 Map이 필요하다.
선택 가이드
이 세 질문에 답하면 대부분의 선택은 거의 자동으로 정해집니다.
요약
- ✅ List는 순서 있는 값의 모음이다.
- ✅ Set은 중복 없는 값의 집합이다.
- ✅ Map은 키로 값을 찾는 관계형 구조다.
- ✅ 구조 선택은 “무엇을 저장하느냐”보다 “어떻게 찾고 사용할 것이냐”로 결정해야 한다.
- ✅ 구현체까지 함께 고려해야 실제 성능과 동작 방식이 맞아진다.