Java Collection Framework 정리

2 min read


Java 초기 버전 (1.0)에서도 자바는 Vector, Stack, Hashtable과 같은
몇 가지 컬렉션 클래스를 제공했다.
이 초기 컬렉션들은 데이터를 관리하는 기본적인 기능을 제공했지만,
아래와 같은 몇 가지 문제점이 존재했다.

  1. 일관성 부족
    • 초기 컬렉션 클래스들은 각기 다른 인터페이스와 동작으로 구성
  2. 확장성 제한
    • 상속을 통한 확장
    • 내부 구현에 의존하는 방식으로 인해, 새로운 컬렉션 타입이나 기존 클래스 확장에 한계 존재
  3. 동기화 오버 헤드
    • 메서드 수준에서의 동기화 제공
    • 당시 환경 (CPU 코어가 1개)에서는 불필요한 성능 오버헤드 발생

위와 같은 문제점을 해결하고, 보다 일관되고 확장 가능한 컬렉션 구조를 제공하기 위해
Java 1.2 버전에서 Java Collection Framework(JCF)를 도입했다.
그와 동시에 기존의 Vector, Stack, Hashtable 역시 Java Collection Framework(JCF)에 편입시켰다.

JCF의 특징

  • 표준 인터페이스 적용
    • 표준 인터페이스를 제공하여, 다양한 컬렉션 타입을 일관성있게 사용 가능
    • 학습 비용 절감 및 이전 버전의 코드에 대한 호환성 증가
  • 개발 비용 절약
    • 필수 자료구조 및 알고리즘을 미리 구현하여 제공
  • 성능 최적화
    • 여러 구현체들의 성능 최적화
    • 빠른 접근 및 수정 가능
  • 동기화 제어
    • 동기화 필요 여부에 따라 적절한 구현체 선택 가능

JCF의 구조

JFC 구조

  • 학습 목적 상, 인터페이스와 구현 클래스 사이의 추상 클래스는 생략하였다.
  • Collection 인터페이스
    • 모든 컬렉션 클래스의 루트 인터페이스
    • Iterable 인테페이스 확장
    • List, Set, Queue 인터페이스는 해당 인터페이스 확장
  • List 인터페이스
    • 순서가 있는 컬렉션
  • Set 인터페이스
    • 중복을 허용하지 않는 컬렉션
  • Queue 인터페이스
    • FIFO(First In First Out) 또는 우선순위 큐
  • Map 인터페이스
    • 키-값 쌍을 나타내는 컬렉션
    • 데이터 구조의 차이로 인해 Collection 인터페이스를 확장하지 않음

JCF 사용 상 유의점

초기 컬렉션(Vector, Stack, Hashtable) 사용을 지양한다.

  • Vector
    • 자바 공식 문서 상 ArrayList의 사용 권장
  • Stack
    • Vector를 상속받기 때문에 벡터의 모든 메소드 노출
    • 자바 공식 문서 상 Deque의 구현체 사용 권장
  • Hashtable
    • 자바 공식 문서 상
      • 스레드 안전이 필요하지 않은 경우 HashMap의 사용 권장
      • 스레드 안전이 필요한 경우 ConcurrentHashMap의 사용 권장

그 원인은 아래와 같다.

  • 과도한 동기화로 인한 성능 저하
    • 모든 메소드를 synchronized로 선언하여 동기화
    • 메서드 사용시 마다 락 획득/ 해제로 인한 성능 저하
  • 락 경쟁
    • 모든 작업에 잠금(Lock)이 시행
    • 데드락과 같은 동시성 문제 발생
  • 복잡한 멀티스레드 애플리케이션 개발 한계
    • 멀티코어 환경에서의 확장 제한
    • 메소드 수준에서의 동기화만 제공
    • 원자적으로(atomic) 여러 메소드 호출을 위한 추가적인 외부 동기화 필요
    • 고급 동시성 기능 부재

StringBuffer와 같은 클래스에서도 동일한 문제가 발생하였다.