📚 컬렉션
📖 컬렉션이란?
**컬렉션(Collection)**은 여러 데이터를 모아서 관리하는 자료구조입니다. List, Set, Map 세 가지가 있습니다.
💡 List
불변 리스트
fun main() {
// listOf - 읽기 전용
val numbers = listOf(1, 2, 3, 4, 5)
println(numbers[0]) // 1 (첫 번째)
println(numbers.first()) // 1
println(numbers.last()) // 5
println(numbers.size) // 5
// numbers.add(6) // ❌ 불가능
}
가변 리스트
fun main() {
// mutableListOf - 변경 가능
val numbers = mutableListOf(1, 2, 3)
numbers.add(4)
numbers.remove(2)
numbers[0] = 10
println(numbers) // [10, 3, 4]
}
List 연산
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
// 검색
println(numbers.contains(3)) // true
println(3 in numbers) // true
println(numbers.indexOf(3)) // 2
// 슬라이싱
println(numbers.subList(1, 4)) // [2, 3, 4]
println(numbers.take(3)) // [1, 2, 3]
println(numbers.drop(2)) // [3, 4, 5]
// 변환
println(numbers.map { it * 2 }) // [2, 4, 6, 8, 10]
println(numbers.filter { it % 2 == 0 }) // [2, 4]
}
🎯 Set
기본 사용
fun main() {
// setOf - 중복 없음, 순서 없음
val fruits = setOf("사과", "바나나", "사과", "포도")
println(fruits) // [사과, 바나나, 포도]
// 중복 제거
val numbers = listOf(1, 2, 2, 3, 3, 3)
val uniqueNumbers = numbers.toSet()
println(uniqueNumbers) // [1, 2, 3]
}
가변 Set
fun main() {
val colors = mutableSetOf("빨강", "파랑")
colors.add("노랑")
colors.add("빨강") // 중복, 추가 안 됨
println(colors) // [빨강, 파랑, 노랑]
colors.remove("파랑")
println(colors) // [빨강, 노랑]
}
Set 연산
fun main() {
val set1 = setOf(1, 2, 3, 4)
val set2 = setOf(3, 4, 5, 6)
// 합집합
println(set1 union set2) // [1, 2, 3, 4, 5, 6]
// 교집합
println(set1 intersect set2) // [3, 4]
// 차집합
println(set1 subtract set2) // [1, 2]
}
🗺️ Map
기본 사용
fun main() {
// mapOf - 키-값 쌍
val scores = mapOf(
"수학" to 90,
"영어" to 85,
"과학" to 95
)
println(scores["수학"]) // 90
println(scores.get("영어")) // 85
println(scores["체육"]) // null
println(scores.keys) // [수학, 영어, 과학]
println(scores.values) // [90, 85, 95]
}
가변 Map
fun main() {
val scores = mutableMapOf(
"수학" to 90,
"영어" to 85
)
// 추가/수정
scores["과학"] = 95
scores["수학"] = 92 // 수정
// 삭제
scores.remove("영어")
println(scores) // {수학=92, 과학=95}
}
Map 순회
fun main() {
val scores = mapOf(
"수학" to 90,
"영어" to 85,
"과학" to 95
)
// 키-값 쌍으로
for ((subject, score) in scores) {
println("$subject: ${score}점")
}
// 키만
for (subject in scores.keys) {
println(subject)
}
// 값만
for (score in scores.values) {
println(score)
}
}
🎯 실전 예제
학생 성적 관리
data class Student(val name: String, val scores: MutableMap<String, Int>)
fun main() {
val student = Student(
name = "홍길동",
scores = mutableMapOf(
"수학" to 90,
"영어" to 85,
"과학" to 95
)
)
// 과목 추가
student.scores["체육"] = 88
// 평균 계산
val average = student.scores.values.average()
println("${student.name}의 평균: %.1f점".format(average))
// 최고 점수 과목
val best = student.scores.maxByOrNull { it.value }
println("최고 점수: ${best?.key} ${best?.value}점")
}
장바구니
data class Product(val name: String, val price: Int)
class ShoppingCart {
private val items = mutableMapOf<Product, Int>()
fun add(product: Product, quantity: Int = 1) {
items[product] = items.getOrDefault(product, 0) + quantity
println("${product.name} ${quantity}개 추가")
}
fun remove(product: Product) {
items.remove(product)
println("${product.name} 제거")
}
fun getTotal(): Int {
return items.entries.sumOf { (product, quantity) ->
product.price * quantity
}
}
fun printCart() {
println("\n=== 장바구니 ===")
for ((product, quantity) in items) {
println("${product.name}: ${quantity}개 (${product.price * quantity}원)")
}
println("총 금액: ${getTotal()}원")
}
}
fun main() {
val cart = ShoppingCart()
cart.add(Product("노트북", 1500000))
cart.add(Product("마우스", 30000), 2)
cart.add(Product("키보드", 80000))
cart.printCart()
}
단어 빈도수
fun wordFrequency(text: String): Map<String, Int> {
val frequency = mutableMapOf<String, Int>()
val words = text.lowercase().split(" ")
for (word in words) {
frequency[word] = frequency.getOrDefault(word, 0) + 1
}
return frequency
}
fun main() {
val text = "Hello World Hello Kotlin World"
val freq = wordFrequency(text)
println("단어 빈도수:")
for ((word, count) in freq) {
println("$word: $count")
}
// 가장 많이 나온 단어
val most = freq.maxByOrNull { it.value }
println("\n가장 많이 나온 단어: ${most?.key} (${most?.value}번)")
}
전화번호부
class PhoneBook {
private val contacts = mutableMapOf<String, String>()
fun add(name: String, phone: String) {
contacts[name] = phone
println("$name 추가됨")
}
fun find(name: String): String? {
return contacts[name]
}
fun remove(name: String) {
contacts.remove(name)
println("$name 삭제됨")
}
fun listAll() {
println("\n=== 전화번호부 ===")
for ((name, phone) in contacts.toSortedMap()) {
println("$name: $phone")
}
}
}
fun main() {
val phoneBook = PhoneBook()
phoneBook.add("홍길동", "010-1234-5678")
phoneBook.add("김철수", "010-2345-6789")
phoneBook.add("이영희", "010-3456-7890")
phoneBook.listAll()
val number = phoneBook.find("홍길동")
println("\n홍길동 번호: $number")
phoneBook.remove("김철수")
phoneBook.listAll()
}
🔍 유용한 함수들
집계 함수
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
println(numbers.sum()) // 15
println(numbers.average()) // 3.0
println(numbers.max()) // 5
println(numbers.min()) // 1
println(numbers.count()) // 5
}
변환 함수
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
// map - 변환
val doubled = numbers.map { it * 2 }
println(doubled) // [2, 4, 6, 8, 10]
// filter - 필터링
val evens = numbers.filter { it % 2 == 0 }
println(evens) // [2, 4]
// flatMap - 평탄화
val nested = listOf(listOf(1, 2), listOf(3, 4))
println(nested.flatten()) // [1, 2, 3, 4]
}
정렬
fun main() {
val numbers = listOf(5, 2, 8, 1, 9)
println(numbers.sorted()) // [1, 2, 5, 8, 9]
println(numbers.sortedDescending()) // [9, 8, 5, 2, 1]
val names = listOf("Charlie", "Alice", "Bob")
println(names.sorted()) // [Alice, Bob, Charlie]
}
그룹화
fun main() {
val numbers = listOf(1, 2, 3, 4, 5, 6)
// 짝수/홀수로 그룹화
val grouped = numbers.groupBy { if (it % 2 == 0) "짝수" else "홀수" }
println(grouped)
// {홀수=[1, 3, 5], 짝수=[2, 4, 6]}
}
🤔 자주 묻는 질문
Q1. List vs Set vs Map?
A: 용도가 다릅니다!
// List - 순서 있음, 중복 가능
val list = listOf(1, 2, 2, 3) // [1, 2, 2, 3]
// Set - 순서 없음, 중복 불가
val set = setOf(1, 2, 2, 3) // [1, 2, 3]
// Map - 키-값 쌍
val map = mapOf("a" to 1, "b" to 2)
Q2. listOf vs mutableListOf?
A: 불변 vs 가변!
// listOf - 읽기만
val immutable = listOf(1, 2, 3)
// immutable.add(4) // ❌
// mutableListOf - 수정 가능
val mutable = mutableListOf(1, 2, 3)
mutable.add(4) // ✅
Q3. 빈 컬렉션은?
A: emptyList() 사용!
val emptyList = emptyList<Int>()
val emptySet = emptySet<String>()
val emptyMap = emptyMap<String, Int>()
// 또는
val list = listOf<Int>()
val set = setOf<String>()
val map = mapOf<String, Int>()
Q4. Array vs List?
A: 대부분 List 사용!
// Array - 크기 고정, 성능
val array = arrayOf(1, 2, 3)
array[0] = 10 // 수정 가능
// List - 유연함, 권장
val list = listOf(1, 2, 3)
🎬 마치며
컬렉션으로 데이터를 효율적으로 관리하세요!
핵심 정리:
✅ List - 순서 있는 모음
✅ Set - 중복 없는 모음