ch12_컬렉션

통합 문서입니다.


1. 컬렉션 프레임워크

컬렉션 프레임워크

학습 목표


1. 컬렉션이 필요한 이유

배열은 고정 길이, 단일 타입, 기능 제한이 있다.
컬렉션은 가변 크기 + 풍부한 연산 + 표준 API를 제공한다.

핵심 인터페이스:

컬렉션 선택 지도


2. List

특성:

대표 구현:

  1. ArrayList: 조회 빠름, 중간 삽입/삭제 느림
  2. LinkedList: 중간 삽입/삭제 유리, 인덱스 조회 비효율

3. Set

특성:

대표 구현:

  1. HashSet: 해시 기반, 일반적으로 빠름
  2. LinkedHashSet: 입력 순서 유지
  3. TreeSet: 정렬 상태 유지(log n)

4. Map

특성:

대표 구현:

  1. HashMap: 일반적으로 빠른 키 조회
  2. LinkedHashMap: 삽입 순서 유지(LRU 구현에도 활용)
  3. TreeMap: 키 정렬 유지

5. 성능 관점 기초

일반적인 평균 복잡도:

주의:


6. equals/hashCode 계약 (매우 중요)

Set/Map 키에서 객체 동등성은 equals/hashCode 계약에 의존한다.

규칙:

  1. equals가 true면 hashCode도 동일해야 함
  2. 객체 상태가 변해 hashCode가 바뀌면 컬렉션 동작이 깨질 수 있음

값 객체를 키로 쓸 때는 불변 설계가 유리하다.


7. 반복과 수정

for-each 순회 중 구조 변경 시 ConcurrentModificationException이 발생할 수 있다.

안전한 삭제:

Iterator<String> it = list.iterator();
while (it.hasNext()) {
    if (it.next().isBlank()) it.remove();
}

8. 정렬

8.1 자연 정렬 Comparable

객체 내부에 기본 정렬 기준을 정의.

8.2 사용자 정의 정렬 Comparator

상황별 정렬 전략을 외부에서 주입.

list.sort(Comparator.comparing(User::getAge).thenComparing(User::getName));

9. 불변 컬렉션

List<String> fixed = List.of("A", "B");

특징:


10. 동시성 컬렉션

멀티스레드 환경에서 일반 컬렉션은 안전하지 않다.

대안:

동시성 패턴에 맞는 컬렉션 선택이 필요하다.


11. 실무 선택 가이드

  1. 기본 목록: ArrayList
  2. 중복 제거: HashSet
  3. 키 조회: HashMap
  4. 정렬 상태 유지 필요: TreeMap/TreeSet
  5. 순서 보존 + 키 조회: LinkedHashMap

12. 정리


2. 문제

문제

ch12 범위(List/Set/Map, 정렬, equals/hashCode, 반복자) 문제입니다.


A. List

  1. 정수 List에서 최댓값/최솟값/평균을 구하시오.
  2. 리스트 중간 삽입/삭제를 구현하고 인덱스 변화를 확인하시오.
  3. 중복 요소를 유지한 채 빈도수를 계산하시오.

B. Set

  1. 문자열 리스트에서 중복을 제거하시오.
  2. Set의 합집합/교집합/차집합을 구하시오.
  3. LinkedHashSetHashSet의 출력 순서를 비교하시오.

C. Map

  1. 문장에서 단어 빈도수(Map<String, Integer>)를 집계하시오.
  2. 키가 없는 경우 기본값 처리(getOrDefault)를 적용하시오.
  3. entrySet 순회로 키/값을 출력하시오.

D. 정렬

  1. 사용자 객체 리스트를 나이 오름차순으로 정렬하시오(Comparator).
  2. 이름 오름차순 + 나이 내림차순 복합 정렬을 구현하시오.
  3. TreeSet/TreeMap에서 정렬 기준이 어떻게 적용되는지 확인하시오.

E. equals/hashCode

  1. 사용자 정의 클래스 User(id, name)HashSet에 넣어 중복 판별하시오.
  2. equals/hashCode 미구현 시 문제를 재현하고 수정하시오.
  3. mutable 필드를 해시 키로 썼을 때 문제를 재현하시오.

F. 반복자/수정

  1. 리스트 순회 중 조건에 맞는 요소를 안전하게 제거하시오(Iterator).
  2. for-each 중 구조 변경 시 예외가 나는 코드와 수정 코드를 작성하시오.

G. 챌린지

  1. 전화번호부 시스템(Map<String, Contact>)을 작성하시오.
  2. 최근 조회 순서를 유지하는 캐시(LinkedHashMap)를 구현하시오.
  3. 멀티스레드 환경에서 ConcurrentHashMap으로 안전 집계를 구현하시오.

제출 체크리스트

  1. 요구사항(중복/순서/정렬/조회패턴)에 맞는 컬렉션을 선택했는가?
  2. 사용자 정의 객체의 동등성 계약을 맞췄는가?
  3. 순회 중 수정 시 안전한 패턴을 사용했는가?