JAVA 기초

[JAVA 기초] JAVA의 정석 - Ch.11 컬렉션 프레임웍 (정리)

beginner-in-coding 2025. 1. 21. 18:35

Ch.11 컬렉션 프레임웍


-      컬렉션 프레임(Collection Framework)

  • 컬렉션 프레임웍의 핵심 인터페이스
    • 컬렉션 프레임웍: 데이터 집합을 저장하는 클래스들을 표준화한 설계
    • interface Collection을 상속한 대표 인터페이스
      • List: 순서가 있는 집합, 데이터의 중복 허용
      • Set: 순서를 유지하지 않는 데이터의 집합, 중복을 허용하지 않음
    • 그 외
      • Map: 키와 값으로 이루어진 데이터의 집합, 순서 유지되지 않음, 키 중복 X, 값 중복 O
      • Map.Entry 인터페이스
        • Map 인터페이스의 내부 인터페이스
        • key-value를 쌍으로 다루기 위해 사용
  • ArrayList
    • List 인터페이스를 구현  →  데이터의 저장 순서 유지, 중복 허용
    • 기존의 Vector 클래스를 보완
    • Object 배열을 이용해서 데이터를 순서대로 저장
    • 장점: 데이터를 읽고 저장하는데 효율이 좋음
    • 단점: 기존의 배열로부터 새로 생성된 배열로 데이터를 복사해야하기 때문에 변경에서 효율이 떨어짐 
      • 크기를 변경할 수 없음
      • 비순차적인 데이터의 추가 또는 삭제에 시간이 오래 걸림
  • LinkedList
    • 배열의 단점을 보완하고자 나옴
    • 데이터를 서로 연결(링크)되어 있는 형태
      • 각 요소(node)의 구성: 자신의 데이터, 다음 요소의 참조(주소 값)
    • 단방향을 보완하고자 나온 Doubly LinkedList
      • 각 요소(node)의 구성: 자신의 데이터, 다음 요소의 참조(주소 값), 이전 요소의 참조(주소 값)
    • Doubly Linked List를 보완한 Doubly Circular LinkedList
      • 마지막 요소와 첫 번째 요소가 서로의 주소를 알고 있음
    • ArrayList와 LinkedList의 비교
      • 순차적인 추가/삭제의 경우  →  ArrayList
      • 중간 데이터를 추가/삭제하는 경우  →  LinkedList
  • Stack Queue
    • Stack
      • LIFO(Last In Fisrt Out): 첫 번째 요소가 가장 마지막에 출력됨
      • 데이터 입력: push
      • 데이터 출력: pop
      • 활용 예시: 수식 계산, 수식 괄호 검사, 워드프로세서의 undo/redo, 웹브라우저의 뒤로/앞으로
    • Queue
      • FIFO(First In First Out): 첫 번째 요소가 가장 먼저 출력됨
      • 데이터 입력: offer
      • 데이터 출력: poll
      • 활용 예시: 최근 사용 문서, 인쇄 작업 대기 목록, 버퍼(buffer)
    • Priority Queue
      • Queue 인터페이스의 구현체 중 하나
      • 저장된 순서에 상관 없이 우선순위(priority)가 높은 것 부터 출력
      • 각 요소를 힙(Heap)이라는 자료구조 형태로 저장
    • Deque
      • Queue의 변형
      • 양 쪽(front, rear)에서 추가/삭제가 가능
      • Queue 인터페이스 구현체 중 하나
      • ArrayDeque와 LinkedList
      • 데이터 입력: offerFirst, offerLast
      • 데이터 출력: pollFirst, pollLast
  • Iterator, Listiterator, Enumeration
    • 컬렉션에 저장된 요소를 접근하는데 사용하는 인터페이스
    • Enumeration은 Iterator의 구버전
    • ListIterator은 Iterator의 기능을 향상시킴 (List를 구현한 경우, 양방향 조회 기능 추가)
    • Iterator 인터페이스
      • 컬렉션 프레임웍에서 컬렉션에 저장된 요소들을 읽어오는 방법을 표준화
      • 각 요소에 접근하는 기능을 가진 Iterator 인터페이스를 정의
      • Collection 인터페이스에는 Iterator를 반환하는 iterator()를 정의하고 있음
        • 메서드
          • boolean hasNext(): 읽어 올 요소가 남아있는지 확인  
          • Object next(): 다음 요소를 읽어옴
          • void remove(): next()로 읽어온 요소를 삭제
      • Map 인터페이스에는 keySet()이나 valueSet()을 호출해서 iterator 사용 가능
  • Arrays
    • 배열을 다루는데 유용한 메서드들 정의
    • 모든 기본형 배열과 참조형 배열 별로 정의되어 있음
    • Arrays의 주요 메서드
      • 배열의 복사: copyOf(), copyOfRange()
      • 배열 채우기: fill(), setAll()
      • 배열의 정렬과 검색: sort(), binarySearch()
      • 문자열의 비교와 출력: equals(), toString()
      • 배열을 리스트로 변환: setList(Object... a)
  • Comparator Comparable
    • Comparable: 기본 정렬 기준을 구현하는데 사용
      • compareTo(Object o): 두 객체가 같으면 (0), 비교하는 값보다 작으면 (음수), 비교하는 값보다 크면 (양수)
    • Comparator: 기본 정렬 기준 외의 다른 기준으로 정렬하고자할 때 사용
      • compare(Object o1, Object o2): compareTo()와 동작은 같음
      • Arrays.sort()는 배열을 정렬할 때, Comparator을 지정해주지 않으면 저장하는 객체(주로 Comparable을 구현한 클래스의 객체)에 구현된 내용에 따라 정렬
  • HashSet
    • Set 인터페이스를 구현한 가장 대표적인 컬렉션  →  중복을 허용하지 않음
    • LinkedHashSet 클래스: 저장순서를 유지하는 HashSet
    • 기존의 저장된 요소와 같은 것인지 판별하기 위해 추가하려는 요소의 equals()와 hashCode()를 알맞게 재정의해야함
      • 실행중인 애플리케이션 내의 동일한 객체에 대해서 여러번 hashCode()를 호출해도 동일한 값을 반환
      • equals()를 통해서 true를 얻은 객체는 서로 같은 hashCode()를 반환
      • 해싱을 사용하는 컬렉션의 성능을 높이기 위해 다른 int값을 사용하는 것이 좋음
    • HashSet을 이용해서 합집합(addAll()), 차집합(retainAll()), 교집합(removeAll())의 연산이 가능
  • TheeSet
    • 이진 탐색 트리(Binary Search Tree)라는 자료구조의 형태로 데이터를 저장하는 컬렉션 클래스
      • 이진 탐색 트리: 검색/정렬/범위 검색에 높은 성능을 가지고 있음
      • TreeSet은 이진 탐색 트리를 향상시킨 Red-Black Tree로 구현되어 있음
    • Set으로 구현  →  중복된 데이터의 저장 허용 X, 정렬된 위치의 저장 순서를 유지하지 않음
    • 구조
      • 각 노드는 두 개의 노드를 연결될 수 있음
      • 루트 노드라고 불리는 하나의 노드에서 뻗어나감
      • 부모 노드와 자식 노드로 구성
      • 노드의 구성: 왼쪽 자식 노드의 정보, 객체를 저장하기 위한 참조 변수, 오른쪽 자식 노드의 정보
      • 왼쪽 자식의 값 < 부모의 값 < 오른쪽 자식의 값
  • HashMap HashTable
    • HashTable의 새로운 버전: HashMap
    • key-value의 한 쌍과 해싱(hasing)을 사용
      • hasing을 통해 많은 양을 검색하는데 높은 효율
    • HashMap의 내부 클래스인 Entry를 통해 키와 값에 접근 가능(keySet(), valueSet())
    • 중복성
      • 키(key): Map 내에서 유일
      • 값(value): 중복 가능
    • 해싱(hasing)
      • 해시 함수(hash function)을 이용해서 해시 테이블(hash table)에 저장하고 검색하는 기법 의미
      • 해시 함수가 저장되어 있는 데이터를 찾아주기 때문에 대용량/속도 빠름
      • 충돌 발생시 분리 연결법 방안 사용 - 연결리스트 이용
  • TreeMap
    • 이진 검색 트리의 형태로 키와 값이 쌍으로 존재하는 자료구조
    • 검색과 정렬에 유리
      • 검색이나 정렬이 필요한 경우는 TreeMap, 검색이 필요한 경우에는 HashMap 이용
  • Properties
    • HashTable을 상속받은 구현체
    • (Object, Object)  →  (String, String) 형태로 저장하는 단순화된 컬렉션 클래스
    • 사용: 애플리케이션의 환경 설정과 관련된 속성(property)를 저장, 파일로부터 읽기/쓰기 편리
  • Collections
    • 컬렉션과 관련된 메서드를 제공
    • 컬렉션의 동기화
      • 멀티 쓰레드 환경에서는 데이터의 일관성을 유지하기 위해 동기화(synchronized) 필요
      • 컬렉션 클래스의 최근 자료구조들은 필요한 경우에만 Collections 클래스의 동기화 메서드를 이용해서 동기화 옵션을 추가함 (synchronizedList(Collection c))
    • 변경 불가 컬렉션 만들기
      • 읽기 전용
      • 멀티 쓰레드 환경에서 여러 쓰레드가 데이터를 사용하면 손상이 올 수 있으므로 사용 (unmodifiableCollection(Collection c))
    • 싱글톤 컬렉션 만들기
      • 메서드를 통해서만 객체에 접근하게 만듬 (singletonXXX())
    • 한 종류의 데이터만 저장하기 
      • 여러 종류의 객체를 저장할 수 있다는 장점이자 단점이 존재하므로 사용 (checkedXXX(Collection c, Class type))
      • 지네릭스로 대체 가능
  • 컬렉션 클래스 정리 & 요약
    • ArrayList: 배열 기반, 데이터의 추가/삭제에 불리, 순차적인 추가/삭제는 빠름, 임의의 요소에 대한 접근성은 높음
    • LinkedList: 연결 기반, 데이터의 추가/삭제에 용이, 임의의 요소에 대한 접근성이 불리
    • HashMap: 배열과 연결이 된 결합 상태, 추가/삭제/검색/접근성이 모두 용이, 검색에는 최고 성능
    • TreeMap: 연결 기반, 정렬과 검색(범위 검색)에 적합, 검색 성능은 HashMap보다 떨어짐
    • Stack: Vector를 상속받아 구현
    • Queue: LinkedList가 Queue인터페이스를 구현
    • Properties: HashTable을 상속받아 구현
    • HashSet: HashMap을 상속받아 구현
    • LinkedHashMap, LinkedHashSet: HashMap과 HashSet에서 저장 기능을 추가