1. 컬렉션과 제네릭

1.1. 컬렉션(Collection)의 개념

  • 정의: 요소(Element)라고 불리는 객체들의 저장소(컨테이너)

  • 특징

    • 요소의 개수에 따라 크기가 자동으로 조절됨(가변 크기)
    • 요소의 삽입, 삭제 시 위치가 자동으로 이동되어 관리가 용이함
    • 고정 크기인 배열(Array)의 한계를 극복
  • 주요 인터페이스 및 클래스

    • Collection<E>: Set<E>, List<E>, Queue<E>의 상위 인터페이스
    • Map<K, V>: 키(Key)와 값(Value)의 쌍으로 저장하는 별도의 인터페이스
    • 구현 클래스: Vector, ArrayList, LinkedList, HashSet, HashMap

1.2. 제네릭(Generics)

  • 개념

    • 모든 종류의 데이터 타입을 다룰 수 있도록 클래스나 메소드를 일반화하는 기법
    • (C++의 템플릿과 유사)
  • 특징

    • 컬렉션은 제네릭 기법으로 구현되어 있음
    • 타입 매개변수(<E>, <K>, <V>): 요소를 특정 타입으로 국한하지 않고 일반화함
    • 객체만 저장 가능: int, char 등 기본 타입은 저장 불가하며, Wrapper 클래스(Integer, Character 등)를 사용해야 함
    • 자동 박싱/언박싱: JDK 1.5부터 기본 타입 값을 객체로 자동 변환해주므로 사용이 편리해짐
  • 장점

    • 컴파일 시 타입을 체크하여 타입 안전성(Type Safety) 보장
    • 불필요한 타입 캐스팅을 줄이고, ClassCastException 방지
  • 타입 추론의 진화

    • JDK 7: <>(다이아몬드 연산자) 도입으로 생성자에서 타입 생략 가능
    • JDK 10: var 키워드 도입으로 지역 변수 타입 추론 가능

2. 제네릭 컬렉션 활용

2.1. Vector<E>

  • 가변 크기 배열을 구현한 클래스 (동기화 지원)
  • 배열의 길이 제한을 극복하고 요소 개수가 넘치면 자동 확장
  • add(), get(), remove(), size(), capacity() 등의 메소드 제공
  • 중간 삽입/삭제 시 뒤의 요소들이 자동으로 이동함

컬렉션과 자동 박싱/언박싱

// 예제 7-1
// 예제 7-2

컬렉션을 매개변수로 받는 메서드

public void printVector(Vector<Integer> v) {
	for(int i=0; i<v.size(); i++) {
		int n = v.get(i); // 벡터의 i 번째 정수
		System.out.println(n);
	}
}

타입 추론

2.2. ArrayList<E>

  • Vector와 거의 동일하게 가변 크기 배열을 구현
  • 차이점: 스레드 동기화(Synchronization) 기능이 없어 다수 스레드 접근 시 동기화 처리가 필요함 (Vector보다 가볍고 빠름)
  • 가장 대중적으로 사용되는 리스트 컬렉션
// 예제 7-3

2.3. Iterator<E> (반복자)

  • 컬렉션의 요소를 순차적으로 검색하기 위한 인터페이스
  • Vector, ArrayList, LinkedList 등 리스트 구조에서 사용
  • 주요 메소드
    • iterator(): Iterator 객체 반환
    • hasNext(): 다음 요소가 있는지 확인
    • next(): 다음 요소를 리턴
    • remove(): 요소를 삭제
// 예제 7-4

2.4. HashMap<K, V>

  • (Key)와 (Value)의 쌍으로 데이터를 저장
  • 키는 중복될 수 없으며, 값을 검색하기 위한 식별자로 사용됨
  • 삽입(put), 삭제, 검색(get) 속도가 매우 빠름
  • 예제: 영어-한글 단어장, 학생 정보(ID-객체) 관리 등
// 예제 7-5
// 예제 7-6
// 예제 7-7
// 예제 7-8

2.5. LinkedList<E>

  • 요소들이 양방향으로 연결된 구조
  • 맨 앞/뒤, 중간에 요소 삽입/삭제가 용이함
  • 스택(Stack)이나 큐(Queue)로 사용 가능

2.6. Collections 클래스

  • java.util 패키지에 포함된 컬렉션 전용 유틸리티 클래스 (모두 static 메소드)
  • 주요 기능: sort()(정렬), reverse()(반전), max()/min()(최대/최소), binarySearch()(이진 검색)
// 예제 7-9

3. 제네릭 만들기

3.1. 제네릭 클래스 선언

  • 클래스 이름 뒤에 <T>와 같이 타입 매개변수를 추가하여 선언

    • 예: public class MyClass<T> { T val; ... }
  • 타입 매개변수 문자 관례

    • E: Element (요소)
    • T: Type (타입)
    • V: Value (값)
    • K: Key (키)
  • 구체화(Specialization): 객체 생성 시 구체적인 타입(예: String, Integer)을 대입하여 확정

// 예제 7-10

3.2. 제네릭과 배열의 제약

  • 제네릭 클래스 자체의 배열 생성 불가
  • 제네릭 타입의 배열(new T[10]) 생성 불가
    • 해결책: Object 배열을 생성한 후 (T)로 캐스팅하여 사용

3.3. 제네릭 메소드

  • 메소드 선언부에 타입 매개변수를 정의하여 일반화된 메소드 작성

    • 예: public <T> void method(T t) { ... }
  • 호출 시 컴파일러가 인자의 타입을 보고 타입을 자동 추론하므로 타입을 명시하지 않아도 됨

    • 예제: 스택의 내용을 반대로 뒤집는 reverse() 메소드 등
// 예제 7-11