배열과 컬렉션의 차이점
- 길이 차이
- 배열은 고정 길이
- 컬렉션은 가변 길이
- 저장数据类型
- 배열은 기본 자료형과 참조 자료형 모두 저장 가능
- 컬렉션은 참조 자료형만 저장 가능
- 요소 제한
- 배열은 동일한 타입만 저장
- 컬렉션은 다양한 타입 저장 가능 (일반적으로 제네릭 사용)
Collection 인터페이스 주요 메서드
boolean add(E element): 컬렉션 끝에 요소 추가boolean remove(Object obj): 해당 요소 삭제 및 결과 반환void clear(): 모든 요소 제거boolean contains(Object obj): 요소 포함 여부 확인boolean isEmpty(): 비어있는지 확인int size(): 요소 개수 반환boolean addAll(Collection c): 다른 컬렉션의 모든 요소 추가Object[] toArray(): 배열로 변환Iterator iterator(): 반복자 반환
컬렉션 분류
- Collection: 단일 요소 컬렉션 (单열)
- List: 입력 순서 유지, 중복 허용
LinkedList: 연결 리스트, 삽입/삭제 빠름, 동기화 미지원ArrayList: 배열 기반, 랜덤 접근 빠름, 동기화 미지원Vector: 배열 기반, 동기화 지원 (스레드 안전)
- Set: 중복 불허, 내부 정렬
HashSet: 해시 테이블 사용LinkedHashSet: 연결 리스트로 삽입 순서 유지TreeSet: 이진 트리 기반, 자동 정렬
List와 Set의 차이점
| 특성 | List | Set |
|---|---|---|
| 순서 | 입력 순서 보장 | 순서 보장 안됨 |
| 중복 | 허용 | 불허 |
| 인덱스 접근 | 가능 | 불가능 |
List 구현 클래스 상세
1. ArrayList
- 내부 구조: 배열
- 특징: 조회 빠름, 삽입/삭제 느림, 스레드 비안전, 중복 허용
2. LinkedList
- 내부 구조: 이중 연결 리스트
- 특징: 조회 느림, 삽입/삭제 빠름, 스레드 비안전, 중복 허용
- 고유 메서드:
- 추가:
addFirst(),addLast() - 삭제:
removeFirst(),removeLast(),poll(),pop() - 조회:
getFirst(),getLast()
- 추가:
3. Vector
- 내부 구조: 배열
- 특징: 조회 빠름, 삽입/삭제 느림, 스레드 안전, 중복 허용
- 주요 메서드:
addElement(E obj)≡add()E elementAt(int index)≡get()Enumeration<E> elements()≡iterator()
ConcurrentModificationException 방지
반복자 또는 향상된 for문으로 순회 중에는 컬렉션의 추가/삭제 메서드를 사용하지 말아야 한다.
제네릭(Generics)
제네릭 인터페이스 사용 방식
- 구현 클래스에서 구체적인 타입 지정
- 구현 클래스에서 제네릭 유지, 객체 생성 시 타입 결정
제네릭과 상속
제네릭 자체는 상속되지 않으나, 데이터는 상속 관계를 가질 수 있다.
import java.util.ArrayList;
public class GenericTest {
public static void main(String[] args) {
ArrayList<Parent> list1 = new ArrayList<>();
ArrayList<Child> list2 = new ArrayList<>();
ArrayList<GrandChild> list3 = new ArrayList<>();
list1.add(new Parent());
list1.add(new Child());
list1.add(new GrandChild());
}
public static void process(ArrayList<Parent> list) {
// Parent 타입만 허용
}
}
class Parent {}
class Child extends Parent {}
class GrandChild extends Child {}
와일드카드(Wildcard)
?:不确定 타입? extends T: T와 그 하위 클래스 타입 허용? super T: T와 그 상위 클래스 타입 허용
public static void process(ArrayList<? extends Parent> list) {
// Parent의 하위 클래스 모두 허용
}
제네릭 요약
- 정의: JDK5에서 도입, 컴파일 타임에 타입 검증
- 장점: 타입的统一, 런타임 예외를 컴파일 단계에서 발견, 불필요한 형변환 제거
- 제한사항: 기본 자료형 사용 불가, 구체적 타입 지정 시 하위 클래스도 허용, 미지정 시 Object로 처리
- 적용 위치:
- 제네릭 클래스: 클래스명 뒤에 선언
- 제네릭 메서드: 반환 타입 앞에 선언
- 제네릭 인터페이스: 인터페이스명 뒤에 선언
Set 구현 클래스
1. HashSet
- 내부 구조: 해시 테이블
- 특징: 순서 없음, 중복 불허, null 허용, 스레드 비안전
- 중복 검증 원리:
hashCode()→equals()순서 검증
hashCode() 오버라이드 원칙:
- 동일 객체는 동일한 해시값 반환
- 서로 다른 객체는 서로 다른 해시값 반환 (충돌 최소화)
- 해시값이 골고루 분포하도록 XOR 연산 활용
2. LinkedHashSet
- 내부 구조: 연결 리스트 + 해시 테이블
- 특징: 삽입 순서 유지, 중복 불허, 스레드 비안전
3. TreeSet
- 내부 구조: 레드-블랙 트리
- 특징: 자동 정렬, 중복 불허, 스레드 비안전
List vs Set 비교
| 구분 | Set | List |
|---|---|---|
| 조회 | 효율 낮음 | 효율 높음 |
| 삽입/삭제 | 위치 변화 없음 | 다른 요소 위치 변화 |
ArrayList vs LinkedList 사용 시나리오
ArrayList:
- 장점: 연속된 메모리, 조회 성능 우수
- 단점: 삽입/삭제 시 데이터 이동 필요
LinkedList:
- 장점: 비연속 메모리, 삽입/삭제 효율적
- 단점: 조회 시 포인터 순회 필요
Map 인터페이스
Map 순회 방법
- 키集合 이용:
map.keySet()으로 키를Set으로 변환 후 순회 - EntrySet 이용:
map.entrySet()으로 키-값 쌍を取得 - Lambda 표현식:
map.forEach((key, value) -> System.out.println(key + "=" + value));
HashMap
- Map 구현 클래스
- 추가 메서드 없음, Map 인터페이스 메서드直接 사용
- 특징:键 기준 - 순서 없음, 중복 불허, 인덱스 없음
- 중복 검증:
hashCode()와equals()활용 - 커스텀 객체를 키로使用时: 두 메서드 오버라이드 필수
LinkedHashMap
- 삽입 순서 유지
TreeMap
- 특징: 중복 불허, 인덱스 없음, 정렬 가능
- 내부 구조: 레드-블랙 트리
- 정렬 방식:
Comparable인터페이스 구현Comparator생성자 파라미터 전달
Map 구현체 선택 가이드
- 기본:
HashMap(최고의 성능) - 순서 보장 필요:
LinkedHashMap - 정렬 필요:
TreeMap
가변 인자(Variable Arguments)
- 본질: 배열과 동일
- 역할: 여러 데이터 수신
- 형식:
데이터타입... 변수명 - 예시:
int... numbers - 제한:
- 가변 인자는 하나만 존재 가능
- 파라미터 목록의 마지막에 위치해야 함
Collections 유틸리티 클래스
import java.util.ArrayList;
import java.util.Collections;
ArrayList<String> collection = new ArrayList<>();
Collections.addAll(collection, "apple", "banana", "cherry", "date");
Collections.shuffle(collection); // 요소 무작위 섞기
주요 메서드
addAll(Collection, elements):批量 추가shuffle(List): 요소 무작위 섞기