Mutable과 Immutable 컬렉션 - swkim0128/PARA GitHub Wiki
코틀린의 컬렉션(Collection)은 **불변(Immutable)**과 가변(Mutable) 두 가지 종류가 있습니다.
- Immutable 컬렉션: 컬렉션을 생성한 후 변경할 수 없음 (읽기 전용)
- Mutable 컬렉션: 요소를 추가, 수정, 삭제 가능
- 요소를 추가하거나 변경할 수 없음.
- listOf(), setOf(), mapOf() 함수를 사용하여 생성.
예제
fun main() {
val fruits = listOf("Apple", "Banana", "Cherry")
println(fruits[0]) // 출력: Apple
println(fruits.size) // 출력: 3
}🚫 불변 리스트에서는 add(), remove() 등의 메서드를 사용할 수 없음.
fun main() {
val fruits = listOf("Apple", "Banana", "Cherry")
// fruits.add("Orange") // 컴파일 오류 발생!
// fruits[0] = "Grape" // 컴파일 오류 발생!
}- 요소를 추가, 수정, 삭제할 수 있음.
- mutableListOf(), mutableSetOf(), mutableMapOf() 사용.
예제
fun main() {
val animals = mutableListOf("Dog", "Cat", "Horse")
animals.add("Elephant") // 요소 추가
animals.remove("Cat") // 요소 삭제
animals[0] = "Tiger" // 값 변경
println(animals) // 출력: [Tiger, Horse, Elephant]
}| 컬렉션 종류 | 생성 방법 | 요소 추가 | 요소 수정 | 요소 삭제 |
|---|---|---|---|---|
| Immutable List | listOf() | ❌ 불가능 | ❌ 불가능 | ❌ 불가능 |
| Mutable List | mutableListOf() | ✅ 가능 | ✅ 가능 | ✅ 가능 |
| Immutable Set | setOf() | ❌ 불가능 | ❌ 불가능 | ❌ 불가능 |
| Mutable Set | mutableSetOf() | ✅ 가능 | ✅ 가능 | ✅ 가능 |
| Immutable Map | mapOf() | ❌ 불가능 | ❌ 불가능 | ❌ 불가능 |
| Mutable Map | mutableMapOf() | ✅ 가능 | ✅ 가능 | ✅ 가능 |
불변 컬렉션을 가변 컬렉션으로 변환하려면 toMutableList(), toMutableSet(), toMutableMap()을 사용합니다.
예제
fun main() {
val fruits = listOf("Apple", "Banana", "Cherry")
val mutableFruits = fruits.toMutableList() // 가변 리스트로 변환
mutableFruits.add("Orange")
println(mutableFruits) // 출력: [Apple, Banana, Cherry, Orange]
}가변 컬렉션을 불변 컬렉션으로 변환하려면 toList(), toSet(), toMap()을 사용합니다.
예제
fun main() {
val mutableNumbers = mutableListOf(1, 2, 3, 4)
val immutableNumbers = mutableNumbers.toList() // 불변 리스트로 변환
// immutableNumbers.add(5) // 컴파일 오류 발생!
println(immutableNumbers) // 출력: [1, 2, 3, 4]
}✅ Immutable 컬렉션 사용이 권장되는 경우:
- 변경이 필요 없는 데이터를 다룰 때
- 멀티스레드 환경에서 안전하게 사용할 때
- 불필요한 데이터 변경을 방지하고 가독성을 높일 때
✅ Mutable 컬렉션 사용이 권장되는 경우:
- 리스트나 맵의 요소를 동적으로 추가/삭제해야 할 때
- 값이 변경될 가능성이 높은 경우
🚫 Immutable 컬렉션은 요소 변경이 불가능하지만, MutableList로 변환하여 변경할 수 있음.
fun main() {
val immutableList = listOf("A", "B", "C")
val mutableList = immutableList.toMutableList()
mutableList.add("D")
println(mutableList) // 출력: [A, B, C, D]
}불변 리스트를 활용한 안전한 데이터 처리
fun getFruits(): List<String> {
return listOf("Apple", "Banana", "Cherry")
}
fun main() {
val fruits = getFruits()
println(fruits) // 출력: [Apple, Banana, Cherry]
}- getFruits()는 불변 리스트를 반환하므로, 외부에서 리스트를 변경할 수 없음.
가변 컬렉션을 함수에서 사용할 때는 원본 데이터가 변경될 위험이 있습니다.
fun modifyList(list: MutableList<String>) {
list.add("Orange")
}
fun main() {
val fruits = mutableListOf("Apple", "Banana", "Cherry")
modifyList(fruits)
println(fruits) // 출력: [Apple, Banana, Cherry, Orange]
}✅ 원본 데이터를 보호하려면 불변 컬렉션을 사용하거나, 복사본을 만들어 사용해야 합니다.
fun modifyListSafe(list: List<String>): List<String> {
val newList = list.toMutableList()
newList.add("Orange")
return newList
}
fun main() {
val fruits = listOf("Apple", "Banana", "Cherry")
val newFruits = modifyListSafe(fruits)
println(newFruits) // 출력: [Apple, Banana, Cherry, Orange]
}| 특징 | Immutable 컬렉션 | Mutable 컬렉션 |
|---|---|---|
| 요소 추가/삭제 가능 여부 | ❌ 불가능 | ✅ 가능 |
| 스레드 안전성 | ✅ 높음 | ❌ 낮음 |
| 데이터 보호 | ✅ 가능 | ❌ 조작 가능 |
| 변환 가능 여부 | ✅ toMutableList(), toMutableSet() | ✅ toList(), toSet() |
👉 언제 Immutable 컬렉션을 사용해야 할까?
- 데이터를 안전하게 유지해야 하는 경우 (예: API 응답)
- 불필요한 변경을 방지하고, 코드 가독성을 높이고 싶은 경우
👉 언제 Mutable 컬렉션을 사용해야 할까?
- 리스트에 요소를 동적으로 추가/삭제해야 하는 경우
- 컬렉션을 변경할 필요가 있는 경우
🎯 결론: Immutable 컬렉션을 기본으로 사용하고, 필요한 경우에만 Mutable 컬렉션을 사용하자! 🚀