Contents
1. 컬렉션(Collection)1️⃣ 컬렉션이란?2️⃣ 컬렉션의 필요성3️⃣ 자바 컬렉션의 전체 구조4️⃣ Collection 계열 핵심 인터페이스5️⃣ 주요 컬렉션 특징 비교6️⃣ 컬렉션 공통 메서드7️⃣ 제네릭과 컬렉션8️⃣ 컬렉션 선택 기준 🧠 (실무 핵심)9️⃣ 주의사항 ⚠️2. ArrayList1️⃣ ArrayList 란?2️⃣ ArrayList 내부 구조3️⃣ ArrayList 기본 사용법4️⃣ ArrayList의 장점5️⃣ ArrayList의 단점6️⃣ 배열 vs ArrayList vs LinkedList 비교7️⃣ ArrayList가 필요한 경우8️⃣ 실무에서 꼭 알아야 할 포인트 ⚠️9️⃣ 실습3. HashSet1️⃣ HashSet이란?2️⃣ HashSet 내부 구조 (아주 중요)3️⃣ HashSet의 중복 판별 원리4️⃣ 사용 예제5️⃣ HashSet의 장점6️⃣ HashSet의 단점7️⃣ HashSet vs 다른 Set 비교8️⃣ HashSet을 써야 하는 경우9️⃣ 실무에서 자주 쓰는 패턴🔟 실습4. 해시맵(HashMap)1. 컬렉션(Collection)
교재 p.558-562 13.2 컬렉션이란?
1️⃣ 컬렉션이란?
여러 데이터를 효율적으로 저장·관리하기 위한 표준 자료구조 프레임워크
배열의 한계를 보완하고, 자료구조 + 알고리즘을 인터페이스로 표준화한 것
2️⃣ 컬렉션의 필요성
1) ❌ 배열의 한계
int[] arr = new int[3];- 크기 고정 ❌
- 추가/삭제 불편 ❌
- 타입별로 배열 따로 ❌
- 기능 부족 (정렬, 탐색 등)
2) ⭕ 컬렉션의 장점
- 크기 자동 조절
- 다양한 자료구조 제공
- 제네릭으로 타입 안정성
- 풍부한 메서드 지원
3️⃣ 자바 컬렉션의 전체 구조

4️⃣ Collection 계열 핵심 인터페이스
1) List (순서 O, 중복 O)
“줄 세워서 저장”
List<String> list = new ArrayList<>();
list.add("A");
list.add("A");
list.add("B");- 인덱스 접근 가능
- 중복 허용
- 순서 유지
대표 구현체
ArrayList⭐
LinkedList
Vector(거의 안 씀)
2) Set (순서 X, 중복 X)
“집합”
Set<String> set = new HashSet<>();
set.add("A");
set.add("A");// 무시- 중복 제거
- 순서 없음 (일반적으로)
대표 구현체
HashSet⭐
LinkedHashSet(순서 유지)
TreeSet(정렬)
3) Queue (FIFO 구조)
“줄 서서 처리”
Queue<Integer> q = new LinkedList<>();
q.add(1);
q.add(2);
q.poll();// 1- 선입선출
- 작업 큐, 메시지 처리
대표 구현체
LinkedList
PriorityQueue
4) Map 계열 (Key-Value) Collection 계열❌ Map 계열⭕
“사전 구조”
Map<String, Integer> map = new HashMap<>();
map.put("apple",1000);
map.put("banana",2000);- Key 중복 ❌
- Value 중복 ⭕
- 빠른 검색
대표 구현체
HashMap⭐
LinkedHashMap
TreeMap
Hashtable(레거시)
5️⃣ 주요 컬렉션 특징 비교
1) List 구현체
구현체 | 특징 |
ArrayList | 조회 빠름 ⭐ |
LinkedList | 삽입/삭제 유리 |
Vector | 동기화 (구식) |
2) Set 구현체
구현체 | 특징 |
HashSet | 가장 빠름 |
LinkedHashSet | 입력 순서 유지 |
TreeSet | 자동 정렬 |
3) Map 구현체
구현체 | 특징 |
HashMap | 가장 일반적 |
LinkedHashMap | 순서 유지 |
TreeMap | 정렬 |
Hashtable | 동기화 (구식) |
6️⃣ 컬렉션 공통 메서드
메서드 | 반환 타입 | 설명 |
add(E e) | boolean | 요소 추가 |
addAll(Collection<? extends E> c) | boolean | 다른 컬렉션 전체 추가 |
remove(Object o) | boolean | 특정 요소 제거 |
removeAll(Collection<?> c) | boolean | 지정 컬렉션 요소 전체 제거 |
retainAll(Collection<?> c) | boolean | 공통 요소만 남김 |
contains(Object o) | boolean | 요소 포함 여부 |
containsAll(Collection<?> c) | boolean | 모든 요소 포함 여부 |
size() | int | 요소 개수 |
isEmpty() | boolean | 비어 있는지 |
clear() | void | 전체 삭제 |
iterator() | Iterator | 반복자 반환 |
toArray() | Object[] | 배열로 변환 |
toArray(T[] a) | T[] | 타입 배열로 변환 |
equals(Object o) | boolean | 컬렉션 동등성 비교 |
hashCode() | int | 해시 코드 반환 |
➡️
List, Set, Queue 는 모두 Collection 인터페이스를 상속⚠️
Map ❌ → 별도7️⃣ 제네릭과 컬렉션
List<String> list = new ArrayList<>();✔️ 타입 안정성
✔️ 캐스팅 제거
✔️ 컴파일 타임 오류 발견
8️⃣ 컬렉션 선택 기준 🧠 (실무 핵심)
상황 | 선택 |
순서 + 중복 필요 | List |
중복 제거 | Set |
키로 빠른 조회 | Map |
처리 순서 중요 | Queue |
정렬 필요 | Tree 계열 |
9️⃣ 주의사항 ⚠️
1) ❌ 컬렉션은 객체만 저장
List<int> list;// ❌
List<Integer> list;// ⭕2) ❌ 동기화 문제
ArrayList,HashMap→ 스레드 안전 ❌
- 필요 시
Collections.synchronizedListConcurrentHashMap
2. ArrayList
교재 p.566-569 13.4 ArrayList
1️⃣ ArrayList 란?
1) 개념
배열 기반으로 구현된 List 컬렉션
List<String> list = new ArrayList<>();2) 핵심 특징
- 순서 있음 ⭕
- 중복 허용 ⭕
- 인덱스 접근 ⭕
- 크기 자동 조절 ⭕
2️⃣ ArrayList 내부 구조
1) 내부는 배열(Object[])
Object[] elementData;
- 처음엔 작은 배열
- 가득 차면 더 큰 배열을 새로 만들고 복사
📌 보통 1.5배씩 증가
3️⃣ ArrayList 기본 사용법
1) 사용법
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
System.out.println(list.get(1)); // B2) 자주 쓰는 메서드
메서드 | 설명 |
add(E e) | 요소 추가 |
get(int i) | 인덱스로 조회 |
set(int i, E e) | 값 변경 |
remove(int i) | 삭제 |
size() | 크기 |
contains() | 포함 여부 |
4️⃣ ArrayList의 장점
1) 조회 성능이 매우 좋음
list.get(100); // O(1)- 인덱스 기반 접근
- 랜덤 접근에 최적
2) 사용법 단순
- 가장 많이 쓰는 컬렉션
- 학습 비용 낮음
4) 배열보다 유연
- 크기 자동 증가
- 컬렉션 메서드 풍부
5️⃣ ArrayList의 단점
1) ❌ 중간 삽입 / 삭제 느림
list.add(0,"X"); // 느림- 뒤 요소들 전부 이동
- 시간 복잡도 O(n)
2) ❌ 메모리 재할당 비용
- 배열 확장 시
- 전체 복사 발생
3) ❌ 스레드 안전하지 않음
- 멀티스레드 환경 ❌
- 필요 시:
Collections.synchronizedList(newArrayList<>());
6️⃣ 배열 vs ArrayList vs LinkedList 비교
구분 | 배열 | ArrayList | LinkedList |
크기 변경 | ❌ | ⭕ | ⭕ |
조회 | 빠름 | 빠름 ⭐ | 느림 |
삽입/삭제 | 느림 | 느림 | 빠름 |
메모리 | 적음 | 보통 | 많음 |
7️⃣ ArrayList가 필요한 경우
1) ⭕ ArrayList가 좋은 경우
- 조회가 많은 경우
- 순서가 중요한 경우
- 데이터 변경이 잦지 않은 경우
- 일반적인 대부분의 상황 ⭐
2) ❌ 피해야 할 경우
- 앞/중간 삽입·삭제가 매우 빈번
- 큐 구조가 필요할 때
8️⃣ 실무에서 꼭 알아야 할 포인트 ⚠️
1) 초기 용량 지정 (성능 최적화)
List<String> list = new ArrayList<>(1000);- 크기 예측 가능하면 필수
- 재할당 비용 감소
2) Arrays.asList 와의 차이 ⚠️
List<String> list = Arrays.asList("A","B","C");
list.add("D"); // ❌ UnsupportedOperationException- 고정 크기 리스트
- 진짜 ArrayList 아님
9️⃣ 실습
package ex13;
import java.util.ArrayList;
import java.util.List;
public class Collect01 {
public static void main(String[] args) {
// ArrayList arr = new ArrayList(); -> 이렇게 하면 Object 타입으로 만들어짐
List<Integer> arr = new ArrayList(); // 내부적으로 배열(10칸) 만들어짐 [Integer 타입] / List or ArrayList 둘 다 가능
// 1. 추가
arr.add(1);
arr.add(3);
arr.add(5);
// 2. 찾기
System.out.println(arr.get(2));
// 3. 삭제
arr.remove(0);
System.out.println(arr.size());
// 4. contains
boolean isThree = arr.contains(3);
System.out.println(isThree);
// 5. 배열로 출력
for (Integer i : arr) {
System.out.println(i);
}
}
}3. HashSet
교재 p.572-574 13.6 Set
1️⃣ HashSet이란?
1) 개념
중복을 허용하지 않고(Set), 순서를 보장하지 않는 해시(Hash) 기반 컬렉션
Set<String> set = new HashSet<>();2) 핵심 특징
특징 | 설명 |
중복 허용 | ❌ |
저장 순서 | ❌ (보장 안 함) |
내부 구조 | HashMap 기반 |
조회 성능 | 매우 빠름 (평균 O(1)) |
null 허용 | ⭕ (1개만) |
2️⃣ HashSet 내부 구조 (아주 중요)
1) HashMap으로 구현됨
public class HashSet<E> {
private transient HashMap<E, Object> map;
}- Set의 값(E) →
HashMap의 Key
- Value는 의미 없는 더미 객체
set.add("A");
// 내부적으로
map.put("A", PRESENT);👉 중복 여부는 Key 기준
3️⃣ HashSet의 중복 판별 원리
1단계: hashCode()
- 같은 해시값 → 같은 버킷 가능성
2단계: equals()
- 진짜 같은 객체인지 최종 비교
@Override
public int hashCode() { ... }
@Override
public boolean equals(Object o) { ... }📌 둘 다 반드시 올바르게 구현해야 함
4️⃣ 사용 예제
1) 기본 사용
Set<String> set = new HashSet<>();
set.add("A");
set.add("A"); // 무시
set.add("B");
System.out.println(set.size()); // 22) 사용자 정의 객체 저장 (핵심)
class User {
String id;
User(String id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return id.equals(user.id);
}
@Override
public int hashCode() {
return id.hashCode();
}
}Set<User> users = new HashSet<>();
users.add(new User("kim"));
users.add(new User("kim"));
System.out.println(users.size()); // 15️⃣ HashSet의 장점
1) 빠른 성능
add,remove,contains→ 평균 O(1)
2) 중복 제거에 최적
- 로또 번호
- 사용자 ID
- 태그 목록
6️⃣ HashSet의 단점
1) 순서 없음
[A, C, B] // 실행할 때마다 다를 수 있음👉 순서 필요하면:
LinkedHashSet
TreeSet
2) hashCode / equals 의존성
- 구현 잘못하면
- 중복 제거 실패
- 성능 급락
7️⃣ HashSet vs 다른 Set 비교
구분 | HashSet | LinkedHashSet | TreeSet |
순서 | ❌ | ⭕ (입력 순) | ⭕ (정렬) |
성능 | ⭐⭐⭐ | ⭐⭐ | ⭐ |
내부 구조 | 해시 | 해시 + 링크 | 트리 |
정렬 | ❌ | ❌ | ⭕ |
8️⃣ HashSet을 써야 하는 경우
1) ⭕ HashSet이 최선인 경우
- 중복 제거가 목적
- 순서가 중요하지 않을 때
- 빠른 조회가 필요할 때
2) ❌ 피해야 할 경우
- 입력 순서/정렬이 필요할 때
9️⃣ 실무에서 자주 쓰는 패턴
1) 중복 제거
List<String> list = List.of("A", "B", "A");
Set<String> set = new HashSet<>(list);2) contains 성능 활용
if (set.contains("admin")) {
// 빠른 권한 체크
}🔟 실습
package ex13;
import java.util.HashSet;
import java.util.Random;
// 로또 코드 -> HashMap이 자동으로 중복 제거
public class Collect03 {
public static void main(String[] args) {
HashSet<Integer> arr = new HashSet<Integer>();
Random rand = new Random();
int n;
while (true) {
n = rand.nextInt(45)+1;
arr.add(n);
if (arr.size() == 6) break;
}
for (Integer i : arr) {
System.out.print(i + " ");
}
}
}
4. 해시맵(HashMap)
JAVA → 22. 해시(Hash) → 3. 해시맵(HashMap) 참고
Share article