4 분 소요

컬렉션 프레임워크

  • 다수의 객체를 저장해 두고 필요할 때마다 꺼내서 사용하는 경우 효율적인 사용법 필요 ⇒ 배열 이용
    • 배열은 쉽게 생성할 수 있지만 저장할 수 있는 객체 수가 배열 생성 시 결정
    • 불특정 다수 객체 저장하기에 문제
    • 객체 삭제 시 해당 인덱스가 비게 됨
  • 자료 구조 사용
    • 컬렉션 프레임워크의 주요 인터페이스 ⇒ List, Set, Map

List 컬렉션

  • 객체를 일렬로 늘어놓은 구조
  • 객체를 인덱스로 관리하기 때문에 객체를 저장하면 자동 인덱스가 부여되고 인덱스로 검색, 삭제 기능 제공
  • 동일한 객체 중복 저장 가능 ⇒ 동일한 번지 참조
  • null 저장 가능 ⇒ 해당 인덱스 객체 참조하지 않음

ArrayList

  • List 인터페이스의 구현 클래스
  • 저장 용량을 초과한 객체들이 들어오면 자동적으로 저장 용량 늘어남
  • 일반적으로 컬렉션에는 단일 종류의 객체들 저장 ⇒ 제네릭 도입하여 타입 파라미터로 저장할 객체 타입 지정해서 불필요한 타입 변환 제거
  • 배열과 달리 삭제 시 인덱스가 당겨짐 ⇒ 빈번한 객체 삭제와 삽입이 일어나는 곳에서 사용하는 것 좋지 않음
  • 인덱스 검색, 마지막 객체 추가하는 경우 좋은 성능 발휘
  • 고정된 객체들로 List 생성
    • List<T> list = Arrays.asList(T…a);

Vector

  • ArrayList와 동일한 내부 구조
  • 생성 : 저장할 객체 타입을 타입 파라미터로 표기하고 기본 생성자 호출
    • List<E> list = new Vector<E>();
  • ArrayList와 다른 점
    • Vector는 동기화된 메소드로 구성 ⇒ 멀티 스레드가 동시에 메소드들 실행 불가
    • 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제

LinkedList

  • ArrayList와 사용 방법은 똑같지만 내부 구조 다름
  • 인접 참조를 링크해서 체인처럼 관리
  • 특정 인덱스의 객체 삭제, 삽입하면 앞뒤 링크만 변하고 나머지 링크 변경되지 않음 ⇒ 빈번한 객체 삭제, 삽입에서 더 좋은 성능 발휘
  • 생성 : 저장할 객체 타입을 타입 파라미터에 표기하고 기본 생성자 호출
    • List<E> list = new LinkedList<E>;

Set 컬렉션

  • 저장 순서가 유지되지 않음
  • 객체 중복 저장 불가
  • 하나의 null만 저장
  • 인덱스로 객체를 검색해서 가져오는 메소드 없음 ⇒ 전체 객체를 대상으로 한번씩 반복해서 가져오는 반복자 제공

HashSet

  • set 인터페이스의 구현 클래스
  • 생성 : 기본 생성자 호출
    • Set<String> set = new HashSet<String>();
  • 객체들을 순서 없이 저장, 동일한 객체 중복 저장하지 않음
  • 동일한 객체
    • hashCode() 메소드를 호출해서 해시코드 비교 ⇒ 동일한 해시코드 있으면 equals() 메소드로 객체 비교 ⇒ true면 중복 저장 하지 않음

Map 컬렉션

  • 키와 값으로 구성된 Entry 객체를 저장하는 구조
    • 키와 값은 모두 객체
    • 키는 중복 저장 안되지만 값은 중복 저장 가능

HashMap

  • Map 인터페이스를 구현한 대표적인 Map 컬렉션
  • HashMap의 키로 사용할 객체는 hashCode() 와 equals() 메소드를 재정의해서 동등 객체가 될 조건을 정해야 함
    • hashCode()가 같고 equals()가 true
  • 키 값은 주로 String 사용
  • 키, 값 타입 파라미터로 주고 기본 생성자 호출
    • Map<K, V> map = new HashMap<K, V>();
  • 키, 값의 타입은 클래스 및 인터페이스만 가능

Hashtable

  • HashMap과 동일한 내부 구조, 키 조건
  • 동기화된 메소드로 구성 ⇒ 하나의 스레드가 실행 완료해야 다른 스레드를 실행할 수 있음
  • 생성 방법 : 키, 값 타입 지정하고 기본 생성자 호출
    • Map<K, V> map = new Hashtable<K, V>();

Properties

  • Hashtable의 하위 클래스 ⇒ Hashtable의 모든 특징을 그대로 갖고 있음
  • 차이점 : 키와 값을 String 타입으로 제한한 컬렉션
  • 애플리케이션 옵션 정보, 데이터베이스 연결 정보, 국제화 정보가 저장된 파일 읽을 때 주로 사용
  • Properties 객체 생성 load() 메소드 호출

검색 기능 강화시킨 컬렉션

이진 트리 구조

  • 여러 개의 노드가 트리 형태로 연결된 구조
  • 루트 노드라고 불리는 하나의 노드에서부터 시작해 각 노드에 최대 2개의 노드를 연결할 수 있는 구조
  • 부모 - 자식 관계(위가 부모, 아래가 자식)
  • 부모 노드의 값보다 작은 노드는 왼쪽, 큰 노드는 오른쪽에 위치

TreeSet

  • 이진 트리를 기반으로 한 Set 컬렉션
  • 하나의 노드는 노드값인 value와 왼쪽과 오른쪽 자식 노드를 참조하기 위한 두 개의 변수로 구성
  • 생성 : 저장할 객체 타입 파라미터로 표기하고 기본 생성자 호출
    • TreeSet<E> treeSet = new TreeSet<String>();

TreeMap

  • 이진 트리를 기반으로 한 Map 컬렉션
  • TreeSet과 차이점 : 키와 값이 저장된 Map.Entry 저장
  • 객체 저장 시 자동 정렬 ⇒ 부모 키값과 비교해서 키 값이 낮은 것은 왼쪽 자식 노드, 높은 것은 오른쪽 자식 노드에 저장
  • 생성 : 키, 값으로 저장할 객체 타입을 타입 파라미터로 주고 기본 생성자 호출
    • TreeMap<K, V> treeMap = new TreeMap<K, V>();

comparable, comparator

  • TreeSet 객체와 TreeMap 키 자동 오름차순 정렬 ⇒ 숫자 타입은 값, 문자열 타입은 유니코드로 정렬
  • TreeSet 객체와 TreeMap 키가 Comparable 구현하고 있지 않으면 저장하는 순간 ClassCastException 발생
    • 생성자의 매개값으로 정렬자 제공하면 Comparable 비구현 객체도 정렬 가능
    • TreeSet<E> treeSet = new TreeSet<E>( new AscendingComparator() );
    • TreeMap<K, V> treeMap = new TreeMap<K, V>( new DescendingComparator() );
    • comparator 인터페이스의 compare() 메소드 ⇒ 두 객체가 동등하면 0, 비교하는 값보다 앞에 오게 하려면 음수, 뒤로 가게 하려면 양수 리턴하도록 구현

LIFO, FIFO 컬렉션

  • LIFO : 후입선출, 나중에 넣은 객체가 먼저 빠져나가는 자료구조 ⇒ 스택
    • Stack<E> stack = new Stack<E>();
  • FIFO : 선입선출, 먼저 넣은 객체가 먼저 빠져나가는 자료구조 ⇒ 큐
    • Queue<E> queue = new LinkedList<E>();

동기화된 컬렉션

  • 컬렉션 프레임워크의 대부분 클래스는 싱글 스레드 환경에서 사용할 수 있도록 설계
    • 여러 스레드가 동시에 컬렉션에 접근하면 의도치 않게 요소가 변경될 수 있는 불안전한 상태
    • ArrayList, HashSet, HashMap 멀티 스레드 환경에서 안전하지 않음
  • 싱글 스레드 환경에서 사용하다 멀티 스레드 환경으로 전달
    • synchronized() 메소드 사용

병렬 처리를 위한 컬렉션

  • 동기화된 컬렉션은 멀티 스레드 환경에서 하나의 스레드가 요소를 안전하게 처리하게 도와줌 ⇒ 전체 요소를 빠르게 처리하지는 못함
  • ConcurrentHashMap
    • 부분 잠금 사용 ⇒ 전체 요소를 다 사용하지 못하도록 하지 않고 처리하는 요소가 포함된 부분만 잠금
  • ConcurrentLinkedQueue 제공
    • 락-프리(lock-free) 알고리즘 ⇒ 여러 개의 스레드가 동시에 접근할 경우, 잠금을 사용하지 않고도 최소한 하나의 스레드가 안전하게 요소를 저장하거나 얻도록 함