9장. 컬렉션 프레임워크
컬렉션 프레임워크 개요
컬렉션이란?
컬렉션(Collection)은 여러 객체를 저장하고 관리하는 자료구조입니다. 배열과 달리 크기가 동적으로 변경되며, 다양한 자료구조를 제공합니다.
배열의 한계
// 배열의 문제점
int[] numbers = new int[5]; // 크기가 고정됨
// numbers[5] = 10; // 오류! 크기를 넘어섬
컬렉션의 장점
- 동적 크기: 필요에 따라 크기가 자동으로 조정됨
- 다양한 자료구조: List, Set, Map 등 다양한 구조 제공
- 편리한 메서드: 추가, 삭제, 검색 등 편리한 메서드 제공
- 타입 안정성: 제네릭을 사용하여 타입 안정성 보장
컬렉션 프레임워크 구조
Collection (인터페이스)
├── List (인터페이스)
│ ├── ArrayList
│ └── LinkedList
├── Set (인터페이스)
│ └── HashSet
└── Map (인터페이스) - Collection을 상속하지 않음
└── HashMap제네릭(Generic) 사용
컬렉션은 제네릭을 사용하여 타입을 지정합니다.
// 형식: 컬렉션타입<저장할타입> 변수명 = new 컬렉션타입<>();
ArrayList<String> list = new ArrayList<>();
List 인터페이스
List란?
List는 순서가 있는 컬렉션입니다. 중복을 허용하며, 인덱스로 요소에 접근할 수 있습니다.
List의 특징
- 순서 보장: 요소가 추가된 순서대로 저장
- 중복 허용: 같은 값을 여러 번 저장 가능
- 인덱스 접근: 인덱스로 요소에 접근 가능
- 동적 크기: 필요에 따라 크기 자동 조정
ArrayList
ArrayList는 배열을 기반으로 한 List 구현체입니다. 인덱스로 빠르게 접근할 수 있습니다.
ArrayList 생성
// 기본 생성
ArrayList<String> list = new ArrayList<>();
// 초기 용량 지정
ArrayList<String> list = new ArrayList<>(10);
// 다른 컬렉션으로부터 생성
ArrayList<String> list = new ArrayList<>(anotherList);
ArrayList 주요 메서드
| 메서드 | 설명 | 반환값 |
|---|---|---|
add(element) |
요소 추가 | boolean |
add(index, element) |
특정 위치에 요소 추가 | void |
get(index) |
인덱스로 요소 가져오기 | E |
set(index, element) |
인덱스의 요소 변경 | E |
remove(index) |
인덱스로 요소 삭제 | E |
remove(element) |
요소로 삭제 | boolean |
size() |
요소 개수 | int |
isEmpty() |
비어있는지 확인 | boolean |
contains(element) |
요소 포함 여부 | boolean |
indexOf(element) |
요소의 첫 번째 인덱스 | int |
clear() |
모든 요소 삭제 | void |
ArrayList 예제
ArrayList<String> fruits = new ArrayList<>();
// 요소 추가
fruits.add("사과");
fruits.add("바나나");
fruits.add("오렌지");
// 특정 위치에 추가
fruits.add(1, "포도");
// 요소 접근
String fruit = fruits.get(0); // "사과"
// 요소 변경
fruits.set(0, "딸기");
// 요소 삭제
fruits.remove(1); // 인덱스로 삭제
fruits.remove("바나나"); // 요소로 삭제
// 크기 확인
int size = fruits.size();
// 반복문으로 순회
for (String f : fruits) {
System.out.println(f);
}
LinkedList
LinkedList는 연결 리스트를 기반으로 한 List 구현체입니다. 중간 삽입/삭제가 빠릅니다.
LinkedList vs ArrayList
| 구분 | ArrayList | LinkedList |
|---|---|---|
| 구조 | 배열 기반 | 연결 리스트 기반 |
| 인덱스 접근 | 빠름 (O(1)) | 느림 (O(n)) |
| 중간 삽입/삭제 | 느림 (O(n)) | 빠름 (O(1)) |
| 메모리 | 연속된 메모리 | 포인터로 연결 |
| 사용 시기 | 인덱스 접근이 많을 때 | 삽입/삭제가 많을 때 |
LinkedList 예제
LinkedList<String> list = new LinkedList<>();
list.add("첫 번째");
list.add("두 번째");
list.add("세 번째");
// 앞에 추가
list.addFirst("맨 앞");
// 뒤에 추가
list.addLast("맨 뒤");
// 첫 번째 요소
String first = list.getFirst();
// 마지막 요소
String last = list.getLast();
// 첫 번째 요소 삭제
list.removeFirst();
// 마지막 요소 삭제
list.removeLast();
Set 인터페이스
Set이란?
Set은 중복을 허용하지 않는 컬렉션입니다. 순서가 보장되지 않을 수 있습니다.
Set의 특징
- 중복 불가: 같은 요소를 여러 번 추가할 수 없음
- 순서 보장 안 됨: HashSet은 순서가 보장되지 않음
- null 허용: null 값 저장 가능 (하나만)
HashSet
HashSet은 해시 테이블을 사용한 Set 구현체입니다. 빠른 검색 속도를 제공합니다.
HashSet 생성
HashSet<String> set = new HashSet<>();
HashSet<String> set = new HashSet<>(10); // 초기 용량
HashSet<String> set = new HashSet<>(anotherCollection);
HashSet 주요 메서드
| 메서드 | 설명 | 반환값 |
|---|---|---|
add(element) |
요소 추가 | boolean |
remove(element) |
요소 삭제 | boolean |
contains(element) |
요소 포함 여부 | boolean |
size() |
요소 개수 | int |
isEmpty() |
비어있는지 확인 | boolean |
clear() |
모든 요소 삭제 | void |
HashSet 예제
HashSet<String> set = new HashSet<>();
// 요소 추가
set.add("사과");
set.add("바나나");
set.add("오렌지");
set.add("사과"); // 중복 추가 시도 (무시됨)
System.out.println(set.size()); // 3
// 요소 확인
boolean hasApple = set.contains("사과"); // true
// 요소 삭제
set.remove("바나나");
// 반복문으로 순회
for (String item : set) {
System.out.println(item);
}
LinkedHashSet
LinkedHashSet은 HashSet과 유사하지만, 삽입 순서를 유지합니다.
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("사과");
set.add("바나나");
set.add("오렌지");
// 삽입 순서대로 출력됨
for (String item : set) {
System.out.println(item);
}
TreeSet
TreeSet은 정렬된 순서로 요소를 저장합니다.
TreeSet<Integer> set = new TreeSet<>();
set.add(5);
set.add(2);
set.add(8);
set.add(1);
// 정렬된 순서로 출력: 1, 2, 5, 8
for (Integer num : set) {
System.out.println(num);
}
Map 인터페이스
Map이란?
Map은 키(Key)와 값(Value)의 쌍으로 데이터를 저장하는 컬렉션입니다. 키는 중복될 수 없습니다.
Map의 특징
- 키-값 쌍: 키와 값의 쌍으로 저장
- 키 중복 불가: 같은 키는 하나만 존재
- 값 중복 가능: 값은 중복 가능
- 빠른 검색: 키로 값을 빠르게 찾을 수 있음
HashMap
HashMap은 해시 테이블을 사용한 Map 구현체입니다. 키-값 쌍을 저장하고 빠르게 검색할 수 있습니다.
HashMap 생성
HashMap<String, Integer> map = new HashMap<>();
HashMap<String, Integer> map = new HashMap<>(10); // 초기 용량
HashMap<String, Integer> map = new HashMap<>(anotherMap);
HashMap 주요 메서드
| 메서드 | 설명 | 반환값 |
|---|---|---|
put(key, value) |
키-값 쌍 추가/수정 | V (이전 값) |
get(key) |
키로 값 가져오기 | V |
remove(key) |
키로 삭제 | V |
containsKey(key) |
키 존재 여부 | boolean |
containsValue(value) |
값 존재 여부 | boolean |
size() |
요소 개수 | int |
isEmpty() |
비어있는지 확인 | boolean |
clear() |
모든 요소 삭제 | void |
keySet() |
모든 키 반환 | Set<K> |
values() |
모든 값 반환 | Collection<V> |
entrySet() |
모든 키-값 쌍 반환 | Set<Map.Entry<K,V>> |
HashMap 예제
HashMap<String, Integer> scores = new HashMap<>();
// 요소 추가
scores.put("홍길동", 85);
scores.put("김철수", 90);
scores.put("이영희", 88);
// 값 가져오기
int score = scores.get("홍길동"); // 85
// 값 수정
scores.put("홍길동", 95); // 기존 값 덮어쓰기
// 키 존재 확인
boolean exists = scores.containsKey("홍길동"); // true
// 요소 삭제
scores.remove("김철수");
// 모든 키 순회
for (String name : scores.keySet()) {
System.out.println(name + ": " + scores.get(name));
}
// 모든 값 순회
for (Integer score : scores.values()) {
System.out.println(score);
}
// 키-값 쌍 순회
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
LinkedHashMap
LinkedHashMap은 HashMap과 유사하지만, 삽입 순서를 유지합니다.
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("사과", 1000);
map.put("바나나", 2000);
map.put("오렌지", 1500);
// 삽입 순서대로 출력됨
for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}
TreeMap
TreeMap은 키를 정렬된 순서로 저장합니다.
TreeMap<String, Integer> map = new TreeMap<>();
map.put("사과", 1000);
map.put("바나나", 2000);
map.put("오렌지", 1500);
// 키가 정렬된 순서로 출력: 바나나, 사과, 오렌지
for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}
반복자(Iterator)
Iterator란?
Iterator는 컬렉션의 요소를 순회하는 데 사용하는 인터페이스입니다. 모든 컬렉션에서 사용할 수 있습니다.
Iterator 사용법
// Iterator 얻기
Iterator<String> iterator = list.iterator();
// 다음 요소가 있는지 확인
while (iterator.hasNext()) {
// 다음 요소 가져오기
String element = iterator.next();
System.out.println(element);
}
Iterator 주요 메서드
| 메서드 | 설명 | 반환값 |
|---|---|---|
hasNext() |
다음 요소가 있는지 확인 | boolean |
next() |
다음 요소 가져오기 | E |
remove() |
현재 요소 삭제 | void |
Iterator 예제
ArrayList<String> list = new ArrayList<>();
list.add("사과");
list.add("바나나");
list.add("오렌지");
// Iterator 사용
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
// 조건에 따라 삭제
if (fruit.equals("바나나")) {
iterator.remove(); // 안전하게 삭제
}
}
향상된 for 문 vs Iterator
// 향상된 for 문 (간단)
for (String item : list) {
System.out.println(item);
}
// Iterator (삭제 가능)
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (조건) {
iterator.remove(); // 안전하게 삭제
}
}
컬렉션 프레임워크 실습 예제
예제 1: 학생 점수 관리 (ArrayList)
import java.util.ArrayList;
public class StudentScoreManager {
public static void main(String[] args) {
ArrayList<Integer> scores = new ArrayList<>();
// 점수 추가
scores.add(85);
scores.add(90);
scores.add(78);
scores.add(92);
scores.add(88);
// 평균 계산
int sum = 0;
for (int score : scores) {
sum += score;
}
double average = (double) sum / scores.size();
System.out.println("평균: " + average);
// 최댓값 찾기
int max = scores.get(0);
for (int score : scores) {
if (score > max) {
max = score;
}
}
System.out.println("최댓값: " + max);
}
}
예제 2: 중복 제거 (HashSet)
import java.util.HashSet;
public class DuplicateRemover {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("사과");
list.add("바나나");
list.add("사과");
list.add("오렌지");
list.add("바나나");
// HashSet으로 중복 제거
HashSet<String> set = new HashSet<>(list);
System.out.println("원본: " + list);
System.out.println("중복 제거: " + set);
}
}
예제 3: 단어 빈도 계산 (HashMap)
import java.util.HashMap;
public class WordFrequency {
public static void main(String[] args) {
String[] words = {"사과", "바나나", "사과", "오렌지", "바나나", "사과"};
HashMap<String, Integer> frequency = new HashMap<>();
for (String word : words) {
if (frequency.containsKey(word)) {
frequency.put(word, frequency.get(word) + 1);
} else {
frequency.put(word, 1);
}
}
// 결과 출력
for (String word : frequency.keySet()) {
System.out.println(word + ": " + frequency.get(word) + "번");
}
}
}
예제 4: 학생 정보 관리 (종합)
import java.util.*;
public class StudentManager {
public static void main(String[] args) {
// 학생 이름 리스트
ArrayList<String> students = new ArrayList<>();
students.add("홍길동");
students.add("김철수");
students.add("이영희");
// 학생 점수 맵
HashMap<String, Integer> scores = new HashMap<>();
scores.put("홍길동", 85);
scores.put("김철수", 90);
scores.put("이영희", 88);
// 학생 정보 출력
for (String name : students) {
int score = scores.get(name);
System.out.println(name + ": " + score + "점");
}
}
}
컬렉션 선택 가이드
언제 어떤 컬렉션을 사용할까?
| 상황 | 추천 컬렉션 | 이유 |
|---|---|---|
| 순서가 중요하고 중복 허용 | ArrayList |
빠른 인덱스 접근 |
| 중간 삽입/삭제가 많음 | LinkedList |
빠른 삽입/삭제 |
| 중복을 허용하지 않음 | HashSet |
빠른 검색 |
| 정렬이 필요함 | TreeSet |
자동 정렬 |
| 키-값 쌍 저장 | HashMap |
빠른 키 검색 |
| 정렬된 키-값 쌍 | TreeMap |
키 자동 정렬 |
연습 문제
ArrayList 기본
- 1부터 10까지의 숫자를 ArrayList에 저장하고 출력하세요.
중복 제거
- 문자열 리스트에서 중복을 제거하는 프로그램을 작성하세요.
단어 빈도
- 문장에서 각 단어가 몇 번 나타나는지 계산하는 프로그램을 작성하세요.
학생 관리
- 학생 이름과 점수를 HashMap에 저장하고, 평균 점수를 계산하세요.
정렬
- 숫자 리스트를 정렬하는 프로그램을 작성하세요.
종합 예제
- 학생 정보(이름, 나이, 점수)를 관리하는 프로그램을 작성하세요.
다음 장 예고
다음 장에서는 예외 처리(Exception Handling)를 통해 프로그램의 오류를 효과적으로 관리하는 방법을 학습합니다.
'BackEnd > Java' 카테고리의 다른 글
| 11장. 입출력(IO) & 파일 처리 (0) | 2026.01.02 |
|---|---|
| 10장. 예외 처리 (0) | 2026.01.02 |
| # 8장. 객체지향 핵심 개념 (0) | 2026.01.01 |
| 7장. 객체지향 프로그래밍(OOP) 기초 (0) | 2026.01.01 |
| 6장. 메서드(Method) (0) | 2025.12.31 |