본문으로 건너뛰기
김신건의 로그

[Java] Collection

· 수정 · 📖 약 2분 · 849자/단어 #java #collection #fundamentals #interface #jcf
Collection, java.util.Collection, Java Collection, Collection interface, 컬렉션, JCF, Java Collections Framework

정의

java.util.Collection<E>그룹으로 묶인 객체들을 표현하는 최상위 인터페이스. JCF (Java Collections Framework) 의 입구이자, List / Set / Queue / Deque 모두 이를 확장한다.

Collection 자체는 직접 인스턴스화하지 않는다. 하위 인터페이스의 구현체 (ArrayList, HashSet, LinkedList 등) 만이 실제 객체가 된다.

상속 관계:

Iterable<E>
  └─ Collection<E>
       ├─ List<E>     → ArrayList, LinkedList, Vector, CopyOnWriteArrayList
       ├─ Set<E>      → HashSet, LinkedHashSet, TreeSet, CopyOnWriteArraySet
       ├─ Queue<E>    → PriorityQueue, ArrayDeque, ConcurrentLinkedQueue
       │   └─ Deque<E> → ArrayDeque, LinkedList, ConcurrentLinkedDeque
       └─ (Map 은 Collection 이 아니다, 별도 계층)

IMPORTANT

MapCollection 의 자식이 아니다. key-value pair 의 모음이라 일반적인 element 모음과 의미가 달라 별도 계층. Map.entrySet() / Map.keySet() / Map.values()Set/Collection 을 반환해 다리를 놓는다.

핵심 메서드 그룹

추가/삭제

  • add(E e): 원소 추가, 추가 됐으면 true (Set 이 이미 갖고 있으면 false)
  • remove(Object o): 첫 매칭 원소 제거
  • addAll(Collection), removeAll(Collection), retainAll(Collection)
  • clear(): 모두 삭제

조회

  • contains(Object o): 포함 여부
  • containsAll(Collection): 모두 포함하는지
  • size(), isEmpty()
  • iterator(): 순회용 (Iterable 에서 상속)
  • stream(), parallelStream(): Java 8+ Stream API 입구

배열 변환

  • toArray(): Object[] 반환
  • toArray(T[] a): 지정 타입 배열 반환
  • toArray(IntFunction<T[]> generator): Java 11+, 더 명확
Collection<String> c = List.of("a", "b", "c");

Object[] arr1 = c.toArray();                // Object[]
String[] arr2 = c.toArray(new String[0]);    // String[] (관행: 빈 배열 전달)
String[] arr3 = c.toArray(String[]::new);    // String[] (Java 11+ 권장)

Collection 의 약속과 한계

Collection 인터페이스 자체는 순서, 중복 허용, 동기화 에 대한 약속이 없다.

특성CollectionListSetQueue
순서 보장✓ (인덱스)구현 의존✓ (FIFO 등)
중복 허용구현 의존
get(int)

따라서 코드에서 변수 타입을 Collection<E> 로 받으면 인덱스 접근, 정렬, 중복 검사 같은 가정을 못 한다. 함수 매개변수에서 일부러 약한 약속만 쓸 때 유용.

자주 쓰이는 구현 한눈에

구현하위 인터페이스특징
ArrayListList가장 흔한 기본
LinkedListList, Deque양방향 연결 리스트
VectorList레거시 synchronized
CopyOnWriteArrayListList읽기 多, 쓰기 少
HashSetSet해시 기반, 순서 없음
LinkedHashSetSet삽입 순서 유지
TreeSetSet정렬 (Comparable / Comparator)
PriorityQueueQueue힙 기반
ArrayDequeQueue, Deque배열 기반 deque (스택보다 빠름)
ConcurrentLinkedQueueQueue동시성 lock-free

Map 은 별도 계층

Map<K,V>
  ├─ HashMap, LinkedHashMap, TreeMap
  ├─ Hashtable (legacy)
  ├─ ConcurrentHashMap
  └─ EnumMap, IdentityHashMap, WeakHashMap

MapCollection 을 extends 하지 않는다. 다만 다음 메서드로 view 를 제공.

Map<String, Integer> map = ...;
Set<String> keys = map.keySet();              // key 만 Set
Collection<Integer> values = map.values();    // value 모음
Set<Map.Entry<String, Integer>> entries = map.entrySet();  // 쌍

이 view 들을 통해 Collection 인터페이스와 호환된다.

컬렉션 view 와 변경 전파

Map.keySet(), subList(), Arrays.asList() 등은 view 를 반환. view 에 대한 변경이 원본에 전파된다.

Map<String, Integer> map = new HashMap<>(Map.of("a", 1, "b", 2));
Set<String> keys = map.keySet();
keys.remove("a");                // ← map 에서도 "a" 삭제

List<Integer> view = list.subList(1, 3);
view.set(0, 99);                 // ← list[1] = 99

CAUTION

view 의 추가/삭제는 원본에 영향을 준다. 독립 사본이 필요하면 new ArrayList<>(view), new HashSet<>(keys) 등으로 명시적 복사.

불변 컬렉션 (Java 9+)

List.of(), Set.of(), Map.of() 가 추가됐다. 반환되는 컬렉션은:

  • immutable: add/remove/clear 호출 시 UnsupportedOperationException
  • null 거부: null 원소를 넣으면 NullPointerException
  • 구조 공유 없음: 안전한 공유 가능
List<Integer> primes = List.of(2, 3, 5, 7);
Set<String> langs = Set.of("Java", "Kotlin", "Scala");
Map<String, Integer> ages = Map.of("Alice", 30, "Bob", 25);

기존 Collections.unmodifiableList(...) 보다 권장.

동기화 (synchronized) 래퍼

Collections.synchronizedXxx(...) 가 모든 메서드를 synchronized 로 감싼 래퍼를 반환.

List<Integer> safe = Collections.synchronizedList(new ArrayList<>());
Map<String, Integer> safeMap = Collections.synchronizedMap(new HashMap<>());
Set<Integer> safeSet = Collections.synchronizedSet(new HashSet<>());

Vector 와 비슷한 메서드별 락 패턴. 복합 연산은 외부 동기화 필요.

synchronized (safe) {            // ← 외부 동기화 필수
    for (Integer x : safe) {     // 순회도 락 안에서
        ...
    }
}

진짜 동시성에는 CopyOnWriteArrayList, ConcurrentHashMap 등 동시성 컬렉션 권장.

Collection 의 함정 정리

1. Collection.removeAll(c) 비용

list.removeAll(otherList);   // O(n × m), otherList 가 List 면 contains 가 O(m)
list.removeAll(otherSet);    // O(n), Set 의 contains 가 O(1)

removeAll 의 매개변수는 contains() 가 빠른 컬렉션을 넘기는 게 좋다.

2. Collection.equals 는 List/Set 별로 다르다

List<Integer> a = List.of(1, 2);
Set<Integer> b = Set.of(1, 2);
a.equals(b);   // false! List.equals 와 Set.equals 의 의미가 다름

Collection 자체는 equals 의미를 명세하지 않음. 하위 인터페이스가 정의.

3. raw type 금지

// ❌ Java 5 이전 스타일
Collection c = new ArrayList();
c.add("hello");
c.add(42);     // 컴파일은 됨, 런타임에 ClassCastException

// ✓ generic
Collection<String> c = new ArrayList<>();

참고

이 글의 용어 (9개)
[Java] ArrayListjava
정의 는 동적 배열 (dynamic array) 로 구현된 . 내부적으로 를 들고 다니며, 용량이 부족해지면 새 배열로 옮긴다. Java 의 가장 흔한 컬렉션 구현체. 인덱스 기…
[Java] ConcurrentHashMapjava
정의 는 고동시성 환경에서 사용 가능한 구현. JSR-166 (Java 5) 도입, Java 8 에서 내부 구조가 크게 재작성됐다. 과 같은 인터페이스를 제공하면서 thread-…
[Java] CopyOnWriteArrayListjava
정의 는 쓰기 시 배열 전체를 복사 하는 thread-safe 구현. 읽기에는 lock 이 전혀 없고, 쓰기에는 으로 직렬화한다. (JSR-166) 의 컬렉션. 읽기 압도적 다,…
[Java] Fail-Fast Iteratorjava
정의 Fail-Fast Iterator 는 순회 도중 컬렉션의 구조가 변경되면 즉시 을 던지는 iterator. , , 등 대부분의 컬렉션의 iterator 가 이 방식. 목적은…
[Java] Iterablejava
정의 는 루프로 순회 가능한 모든 타입의 최상위 인터페이스. 단 하나의 추상 메서드, 를 정의한다. 인터페이스가 을 extends 하므로 , , , 등 모든 컬렉션이 자동으로 대…
[Java] LinkedListjava
정의 는 양방향 연결 리스트 (doubly linked list) 로 구현된 이자 . 각 원소는 와 포인터를 가진 노드로 보관된다. 와 같은 List 이지만, 메모리 레이아웃과 …
[Java] Listjava
정의 는 순서가 있고 중복이 허용 되는 컬렉션을 표현하는 인터페이스. 각 원소는 0 부터 시작하는 정수 인덱스로 접근 가능. 인터페이스를 확장하며, 의 모든 성질을 물려받는다. …
[Java] Objectjava
정의 는 Java 의 모든 클래스의 최상위 부모 (root) 클래스. 가 명시되지 않은 클래스는 컴파일러가 자동으로 를 붙인다. 인터페이스는 클래스가 아니라 를 직접 상속하지는 …
Geometry Basic: 벡터, CCW, 외적, 내적algorithm
정의 기하 알고리즘의 밑바탕. 대부분의 2D/3D 기하 문제는 벡터 연산, 내적/외적, CCW 판정 세 가지의 조합으로 풀립니다. 벡터 2D 벡터: 두 점 $A = (ax, ay…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기