1. 컬렉션과 제네릭
1.1. 컬렉션(Collection)의 개념
-
정의: 요소(Element)라고 불리는 객체들의 저장소(컨테이너)
-
특징
- 요소의 개수에 따라 크기가 자동으로 조절됨(가변 크기)
- 요소의 삽입, 삭제 시 위치가 자동으로 이동되어 관리가 용이함
- 고정 크기인 배열(Array)의 한계를 극복
-
주요 인터페이스 및 클래스
- Collection<E>:
Set<E>,List<E>,Queue<E>의 상위 인터페이스 - Map<K, V>: 키(Key)와 값(Value)의 쌍으로 저장하는 별도의 인터페이스
- 구현 클래스:
Vector,ArrayList,LinkedList,HashSet,HashMap등
- Collection<E>:
1.2. 제네릭(Generics)
-
개념
- 모든 종류의 데이터 타입을 다룰 수 있도록 클래스나 메소드를 일반화하는 기법
- (C++의 템플릿과 유사)
-
특징
- 컬렉션은 제네릭 기법으로 구현되어 있음
- 타입 매개변수(<E>, <K>, <V>): 요소를 특정 타입으로 국한하지 않고 일반화함
- 객체만 저장 가능:
int,char등 기본 타입은 저장 불가하며, Wrapper 클래스(Integer,Character등)를 사용해야 함 - 자동 박싱/언박싱: JDK 1.5부터 기본 타입 값을 객체로 자동 변환해주므로 사용이 편리해짐
-
장점
- 컴파일 시 타입을 체크하여 타입 안전성(Type Safety) 보장
- 불필요한 타입 캐스팅을 줄이고,
ClassCastException방지
-
타입 추론의 진화
- JDK 7:
<>(다이아몬드 연산자) 도입으로 생성자에서 타입 생략 가능 - JDK 10:
var키워드 도입으로 지역 변수 타입 추론 가능
- JDK 7:
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-32.3. Iterator<E> (반복자)
- 컬렉션의 요소를 순차적으로 검색하기 위한 인터페이스
Vector,ArrayList,LinkedList등 리스트 구조에서 사용- 주요 메소드
iterator(): Iterator 객체 반환hasNext(): 다음 요소가 있는지 확인next(): 다음 요소를 리턴remove(): 요소를 삭제
// 예제 7-42.4. HashMap<K, V>
- 키(Key)와 값(Value)의 쌍으로 데이터를 저장
- 키는 중복될 수 없으며, 값을 검색하기 위한 식별자로 사용됨
- 삽입(
put), 삭제, 검색(get) 속도가 매우 빠름 - 예제: 영어-한글 단어장, 학생 정보(ID-객체) 관리 등
// 예제 7-5
// 예제 7-6
// 예제 7-7
// 예제 7-82.5. LinkedList<E>
- 요소들이 양방향으로 연결된 구조
- 맨 앞/뒤, 중간에 요소 삽입/삭제가 용이함
- 스택(Stack)이나 큐(Queue)로 사용 가능
2.6. Collections 클래스
java.util패키지에 포함된 컬렉션 전용 유틸리티 클래스 (모두 static 메소드)- 주요 기능:
sort()(정렬),reverse()(반전),max()/min()(최대/최소),binarySearch()(이진 검색)
// 예제 7-93. 제네릭 만들기
3.1. 제네릭 클래스 선언
-
클래스 이름 뒤에
<T>와 같이 타입 매개변수를 추가하여 선언- 예:
public class MyClass<T> { T val; ... }
- 예:
-
타입 매개변수 문자 관례
- E: Element (요소)
- T: Type (타입)
- V: Value (값)
- K: Key (키)
-
구체화(Specialization): 객체 생성 시 구체적인 타입(예:
String,Integer)을 대입하여 확정
// 예제 7-103.2. 제네릭과 배열의 제약
- 제네릭 클래스 자체의 배열 생성 불가
- 제네릭 타입의 배열(
new T[10]) 생성 불가- 해결책:
Object배열을 생성한 후(T)로 캐스팅하여 사용
- 해결책:
3.3. 제네릭 메소드
-
메소드 선언부에 타입 매개변수를 정의하여 일반화된 메소드 작성
- 예:
public <T> void method(T t) { ... }
- 예:
-
호출 시 컴파일러가 인자의 타입을 보고 타입을 자동 추론하므로 타입을 명시하지 않아도 됨
- 예제: 스택의 내용을 반대로 뒤집는
reverse()메소드 등
- 예제: 스택의 내용을 반대로 뒤집는
// 예제 7-11