TIL/[TIL]

[TIL]Java Collection Framework, List / Set / Map 핵심 정리

namerong 2026. 5. 11. 17:27

1. 학습 주제

자바 컬렉션 프레임워크의 기본 구조와 대표 자료구조인 List, Set, Map을 정리했다.
이번 범위는 전부 중요하지만, 그중에서도 특히 핵심은 “어떤 상황에서 어떤 컬렉션을 선택해야 하는가”와 “중복, 순서, 키-값 구조를 어떻게 구분하느냐”라고 느꼈다.

  • 컬렉션 프레임워크의 전체 구조 이해하기
  • List, Set, Map의 차이 명확히 구분하기
  • ArrayList와 LinkedList의 특징 이해하기
  • Stack, Queue의 동작 방식 익히기
  • Set에서 중복 제거와 순서 처리 방식 이해하기
  • Map에서 key-value 구조와 순회 방식 익히기
  • 정렬과 Comparable, Comparator 역할 정리하기

2. 컬렉션 프레임워크란

컬렉션 프레임워크는 여러 개의 데이터를 효율적으로 저장하고 관리하기 위해 자바에서 제공하는 클래스와 인터페이스의 묶음이다.

기본 자료형 배열과 비교하면 컬렉션은 다음 장점이 있다.

  • 크기를 유연하게 늘리고 줄일 수 있다
  • 데이터 추가, 삭제, 검색, 정렬 기능을 쉽게 사용할 수 있다
  • 목적에 맞는 자료구조를 선택할 수 있다

대표 분류는 다음 세 가지이다.

  • List : 순서가 있고 중복 허용
  • Set : 중복 불가, 순서 없음 또는 제한적
  • Map : key-value 쌍으로 저장

이 세 가지 차이를 정확히 구분하는 것이 이번 범위의 가장 핵심이다.


3. List, Set, Map 차이

이 부분은 꼭 명확하게 정리해야 한다.

3.1 List

  • 저장 순서를 유지한다
  • 중복 저장이 가능하다
  • 인덱스로 접근할 수 있다

예:

["banana", "apple", "apple", "grape"]
  • apple이 두 번 들어갈 수 있다
  • 0번, 1번처럼 위치로 접근할 수 있다

즉 List는 “줄 세워서 보관하는 자료구조”라고 이해하면 쉽다.

3.2 Set

  • 중복 저장이 불가능하다
  • 보통 인덱스가 없다
  • 순서를 보장하지 않거나, 구현체에 따라 일부 유지한다

예:

["html", "css", "java"]
  • 같은 값 html을 또 넣으면 저장되지 않는다
  • get(0)처럼 인덱스로 꺼낼 수 없다

즉 Set은 “중복 없는 집합”이다.

3.3 Map

  • key와 value를 한 쌍으로 저장한다
  • key는 중복 불가
  • value는 중복 가능
  • 인덱스가 아니라 key로 조회한다

예:

{"one"="java", "two"="html", "three"="mysql"}
  • "two"라는 키가 이미 있으면 값이 덮어써진다
  • get("two")처럼 키로 값을 찾는다

즉 Map은 “사전”처럼 보는 게 가장 쉽다.

3.4 한 줄 비교

  • List : 순서 중요, 중복 허용
  • Set : 중복 제거 중요
  • Map : 키로 빠르게 값 찾기 중요

4. List

List는 가장 자주 쓰는 컬렉션이다.
데이터를 순서대로 저장하고, 같은 값도 여러 번 넣을 수 있다.

List<String> stringList = new ArrayList<>();
stringList.add("banana");
stringList.add("apple");
stringList.add("apple");
stringList.add("grape");

여기서 중요한 포인트는:

  • 입력 순서가 유지된다
  • 같은 값도 여러 번 저장 가능하다
  • 인덱스로 접근 가능하다
stringList.set(2, "mango");
stringList.remove(1);
stringList.size();

즉 List는 배열처럼 다루되, 크기가 유동적이고 기능이 더 많은 구조라고 볼 수 있다.

4.1 List가 중요한 이유

실무나 학습에서 “여러 개를 순서대로 관리”하는 상황이 가장 많기 때문이다.

예:

  • 학생 목록
  • 게시글 목록
  • 주문 목록
  • 책 목록

이런 건 대부분 List로 시작한다고 생각해도 된다.


5. ArrayList와 LinkedList

둘 다 List이지만 내부 구조가 다르다.

5.1 ArrayList

  • 내부적으로 배열 기반
  • 조회가 빠르다
  • 중간 삽입/삭제는 상대적으로 비효율적일 수 있다

5.2 LinkedList

  • 각 요소가 앞뒤 요소와 연결된 구조
  • 중간 삽입/삭제는 비교적 유리하다
  • 특정 위치 조회는 느릴 수 있다

예제 설명 그대로 핵심만 잡으면:

  • 많이 읽고 조회할 때: ArrayList
  • 중간 삽입/삭제가 많을 때: LinkedList

처음엔 대부분 ArrayList를 기본으로 쓰고, 필요할 때 LinkedList를 고려하는 흐름이 자연스럽다.


6. List 정렬과 Comparable / Comparator

컬렉션에서 정렬은 매우 중요하다.

6.1 문자열 정렬

Collections.sort(stringList);
  • 문자열은 기본 정렬 기준이 이미 있어서 바로 정렬 가능하다

6.2 객체 정렬

객체는 기준이 없으면 정렬할 수 없다.
그래서 정렬 기준을 정해줘야 한다.

Comparable

객체 내부에 “기본 정렬 기준”을 만든다.

public class BookDTO implements Comparable<BookDTO> {
    @Override
    public int compareTo(BookDTO o) {
        return Integer.compare(this.number, o.getNumber());
    }
}
  • BookDTO는 기본적으로 번호 오름차순 정렬을 가진다
  • Collections.sort(bookList)만 써도 정렬 가능하다

Comparator

외부에서 정렬 기준을 따로 만든다.

public class AscendingPrice implements Comparator<BookDTO> {
    @Override
    public int compare(BookDTO o1, BookDTO o2) {
        return Integer.compare(o1.getPrice(), o2.getPrice());
    }
}
  • 가격순, 제목순처럼 상황마다 기준을 바꾸고 싶을 때 유용하다

정리하면:

  • Comparable : 객체 자체의 기본 정렬 기준
  • Comparator : 외부에서 갈아끼우는 정렬 기준

이 차이는 꼭 알아야 한다.


7. Stack과 Queue

둘 다 순서가 있지만, 꺼내는 방식이 다르다.

7.1 Stack

후입선출, LIFO

stack.push(1);
stack.pop();
stack.peek();
  • 마지막에 넣은 것이 먼저 나온다
  • 책 더미처럼 위에 쌓는 구조라고 생각하면 쉽다

7.2 Queue

선입선출, FIFO

queue.offer("first");
queue.poll();
queue.peek();
  • 먼저 들어온 것이 먼저 나온다
  • 줄 서는 구조라고 생각하면 쉽다

이 둘은 List의 확장 개념처럼 보일 수 있지만, 실제로는 “꺼내는 규칙”이 가장 중요한 자료구조이다.


8. Set

Set은 중복 제거가 가장 핵심이다.

Set<String> hset = new HashSet<>();
hset.add("html");
hset.add("css");
hset.add("java");
boolean isAdded = hset.add("html");
  • 중복된 html은 추가되지 않는다
  • add() 결과가 false가 된다

8.1 Set의 핵심 특징

  • 중복 불가
  • 인덱스 없음
  • 순서 보장이 약함

그래서 Set은 이런 상황에 어울린다.

  • 중복 제거
  • 유일한 값만 관리
  • 회원 ID 중복 체크
  • 태그, 과목명, 기술 스택처럼 겹치면 안 되는 데이터 저장

8.2 순회 방법

Set은 인덱스가 없기 때문에 List처럼 get()을 사용할 수 없다.

대신:

  • toArray()
  • iterator()
  • 향상된 for문

같은 방식으로 전체 순회한다.


9. HashSet, LinkedHashSet, TreeSet

이 세 가지 구분도 중요하다.

9.1 HashSet

  • 중복 불가
  • 순서 없음

가장 기본적인 Set이다.

9.2 LinkedHashSet

  • 중복 불가
  • 입력 순서 유지

Set이지만 순서를 어느 정도 유지하고 싶을 때 사용한다.

9.3 TreeSet

  • 중복 불가
  • 자동 오름차순 정렬
Set<Integer> lotto = new TreeSet<>();

로또 번호 예제가 TreeSet의 장점을 잘 보여준다.

  • 중복은 자동 제거
  • 정렬도 자동 처리

즉 TreeSet은 “중복 제거 + 정렬”이 동시에 필요할 때 강력하다.

9.4 아주 중요한 포인트

TreeSet은 정렬이 필요하므로 요소가 비교 가능해야 한다.

  • String, Integer는 이미 가능
  • 사용자 정의 객체는 Comparable 구현이 필요하다

10. Map

Map은 List나 Set과는 완전히 다르게, key-value 쌍으로 데이터를 저장한다.

Map<String, String> hmap = new HashMap<>();
hmap.put("one", "java");
hmap.put("two", "java");
hmap.put("three", "mysql");
hmap.put("two", "html");

여기서 핵심은:

  • key는 중복 불가
  • value는 중복 가능
  • 같은 key를 다시 넣으면 값이 덮어써진다

즉 Map은 “값 하나를 찾기 위해 이름표(key)를 붙여놓은 구조”이다.

10.1 왜 중요한가

List는 순번으로 찾고, Set은 중복 제거 중심이지만,
Map은 “이 이름에 해당하는 값이 뭐지?”를 빠르게 찾는 데 특화되어 있다.

예:

  • 회원 ID -> 회원 정보
  • 상품 코드 -> 상품 객체
  • 설정 이름 -> 설정 값
  • 과목명 -> 점수

11. Map의 핵심 메서드

저장

hmap.put("one", "java");

조회

hmap.get("one");

키 존재 여부 확인

hmap.containsKey("three");

기본값 처리

hmap.getOrDefault("없는키", "기본값");

삭제

hmap.remove("four");

실무에서는 get() 결과가 null일 수 있으므로,
containsKey()나 getOrDefault()를 같이 쓰는 습관이 중요하다.


12. Map 순회

Map은 key-value 구조이기 때문에 순회 방법도 List, Set과 다르다.

12.1 keySet()

키만 꺼내서 순회

Set<String> keys = hmap.keySet();
for(String key : keys){
    System.out.println(key + " = " + hmap.get(key));
}

12.2 values()

값만 꺼낼 때

Collection<String> values = hmap.values();

12.3 entrySet()

키와 값을 함께 다룰 때 가장 효율적

Set<Map.Entry<String, String>> entrySet = hmap.entrySet();
for(Map.Entry<String, String> entry : entrySet){
    System.out.println(entry.getKey() + " = " + entry.getValue());
}

보통 key와 value를 함께 써야 한다면 entrySet()이 가장 자연스럽다.


13. Properties

Properties는 Map의 특수한 형태이다.

Properties prop = new Properties();
prop.setProperty("driver", "com.mysql.cj.jdbc.Driver");

특징:

  • key와 value가 모두 String
  • 설정 정보 저장에 자주 사용

예:

  • DB 연결 정보
  • 환경 설정
  • 프로그램 옵션 값

즉 Properties는 “설정 파일용 Map”처럼 이해하면 쉽다.


14. 가장 핵심적인 부분 정리

이번 범위에서 특히 더 중요하게 느껴지는 부분은 아래 네 가지이다.

14.1 컬렉션 선택 기준

무조건 외우기보다, 저장 목적을 먼저 생각해야 한다.

  • 순서가 중요하면 List
  • 중복 제거가 중요하면 Set
  • 키로 찾는 구조면 Map

14.2 정렬

문자열이나 숫자는 그냥 정렬되지만, 객체는 기준이 필요하다.

  • 기본 기준 1개면 Comparable
  • 상황마다 바뀌면 Comparator

14.3 Set과 중복

Set은 중복을 허용하지 않기 때문에 “중복 제거용”으로 매우 자주 쓰인다.
특히 TreeSet은 정렬까지 같이 처리할 수 있어서 활용도가 높다.

14.4 Map과 key-value 사고방식

Map은 단순히 “두 개를 같이 저장하는 구조”가 아니라,
“이 key로 바로 value를 찾는다”는 관점으로 이해해야 한다.


15. 흐름 정리

15.1 List

  • 순서 유지
  • 중복 허용
  • 인덱스 접근 가능
  • ArrayList, LinkedList, Stack, Queue 학습

15.2 Set

  • 중복 불가
  • 인덱스 없음
  • HashSet, LinkedHashSet, TreeSet 차이 학습
  • 중복 없는 로또 번호 생성 예제로 활용

15.3 Map

  • key-value 쌍 저장
  • key는 중복 불가
  • HashMap, Properties 활용
  • keySet, values, entrySet 순회 방식 학습

16. 핵심 정리

  1. 컬렉션 프레임워크는 여러 객체를 효율적으로 관리하기 위한 구조이다.
  2. List는 순서를 유지하고 중복을 허용한다.
  3. Set은 중복을 허용하지 않으며, 보통 인덱스로 접근하지 않는다.
  4. Map은 key-value 쌍으로 데이터를 저장하며 key는 중복될 수 없다.
  5. ArrayList는 조회에 강하고, LinkedList는 중간 삽입/삭제에 상대적으로 유리하다.
  6. Stack은 후입선출, Queue는 선입선출 구조이다.
  7. 객체 정렬은 Comparable이나 Comparator가 필요하다.
  8. HashSet은 순서 없고, LinkedHashSet은 입력 순서를 유지하며, TreeSet은 자동 정렬된다.
  9. Map을 순회할 때 key와 value를 함께 다루려면 entrySet()이 편리하다.
  10. 컬렉션을 잘 쓰려면 “순서가 필요한가, 중복을 허용할 건가, 키로 찾을 건가”를 먼저 판단해야 한다.