본문 바로가기
개발새발/코틀린

[코틀린/Kotlin] 컬렉션

by 조희우 2025. 8. 16.

컬렉션

  • 자료 구조를 편하게 다루기 위하여 제공되는 라이브러리
  • 표준 Java Collection을 활용: 자바 코드와 상호작용하기 쉬움

List

  • immutable 컬렉션
    • 읽기 전용: 내용 수정 X
    • MutableList를 활용하여 mutable한 리스트 사용가능
    • 순서가 있는 엘리먼트들의 집합
    • 시퀀스라고도 부름
  • 예시
val list: List<Int> = listOf(1, 2, 3)
//list.add -> 에러
//list[0] = 0 // 에러(list.add와 같은 결과를 나타냄)
//list.set -> 에러

println(list) //출력값 : [1, 2, 3]

println(list[0]) //출력값 : 1
  • MutableList 예시
var mutableList: MutableList<Int> = mutableListOf(1, 2, 3)

mutableList.add(4)
println(mutableList) // 출력값 : [1, 2, 3, 4]

mutableList[0] = 0
println(mutableList) // 출력값 : [0, 2, 3, 4]

mutableList.set(1, 1)
println(mutableList) // 출력값 : [0, 1, 3, 4]

mutableList = mutableList.apply {
	add(5)
	add(6)
}

println(mutableList) // 출력값 : [0, 1, 3, 4, 5, 6]

Array

  • mutable 컬렉션
  • 초기화 당시에 배열 크기 선언: 배열의 크기 변경 불가능
  • 포인터를 사용하여 값의 위치를 가리킴
  • contentToString을 사용하여 내용을 출력
val array: Array<Int> = arrayOf(1, 2, 3, 4, 5)

array.set(0, 6) //첫번째 데이터 값을 6으로 변경
array[0] = 6 //array.set(0, 6)과 같은 결과

println(array) //출력값 : [Ljava.lang.Integer;@330bedb4
println(array.contentToString()) //출력값 : [6, 2, 3, 4, 5]

ArrayList

  • mutable 컬렉션
  • 배열 크기 변경 가능
val arrayList: ArrayList<Int> = arrayListOf(1, 2, 3)

println(arrayList) //출력값 : [1, 2, 3]

arrayList.set(1, 5) //두번째 데이터 값을 5로 변경
arrayList[1] = 5 //arrayList.set(1, 5) 같은 결과

println(arrayList) //출력값 : [1, 5, 3]

arrayList.remove(5) //arrayList 내의 요소 중 "5" 제거

println(arrayList) //출력값 : [1, 3]

Set

  • immutable 컬렉션
    • MutableSet을 활용하여 mutable한 집합 사용 가능
  • 순서가 없는 유일한 요소들의 집합: 중복X
  • 인덱스를 가지지 않음 → 인덱스를 통한 요소 접근 불가능
val set: Set<Int> = setOf(1, 2, 3)
println(set)// 출력값: [1, 2, 3]

// -- MutableSet 예시 --
val mutableSet: MutableSet<Int> = mutableSetOf(1, 2, 3)

mutableSet.add(4)
println(mutableSet) // 출력값 : [1, 2, 3, 4]

// 이미 존재하는 요소를 추가하려고 하면, 아무런 변화 X.
mutableSet.add(2)
println(mutableSet) // 출력값 : [1, 2, 3, 4]

// 요소 삭제
mutableSet.remove(1)
println(mutableSet) // 출력값 : [2, 3, 4]

Map

  • immutable 컬렉션
    • MutableMap을 활용해서 mutable한 map 사용 가능
  • 키-값 쌍의 집합
    • 각 키는 유일하며 키는 하나의 값을 가짐
val map: Map<String, Int> = mapOf("one" to 1, "two" to 2, "three" to 3)
println(map) // 출력값: {one=1, two=2, three=3}

// -- MutableMap 예시 --
val mutableMap: MutableMap<String, Int> = mutableMapOf("one" to 1, "two" to 2, "three" to 3)

mutableMap["four"] = 4
println(mutableMap) // 출력값 : {one=1, two=2, three=3, four=4}

// 이미 존재하는 키의 값을 변경
mutableMap["one"] = 10
println(mutableMap) // 출력값 : {one=10, two=2, three=3, four=4}

// 키-값 쌍 삭제
mutableMap.remove("two") //키 값을 이용해서 삭제함
println(mutableMap) // 출력값 : {one=10, three=3, four=4}

불변/가변 컬렉션

불변 컬렉션

  • 새로운 요소 삽입, 기존 요소 삭제 및 수정 등 변경이 불가능
  • 저장된 요소를 조회만 가능
  • Mutable-이 붙지 않은 iterable, Collection, List, Set, Map은 불변
  • 기본적으로 코틀린은 불변을 지향
  • map()과 같이 컬렉션 객체의 요소와 관련된 연산 수행 후 컬렉션 객체를 반환하는 메소드들은 기본적으로 불변 리스트를 반환 → toMuatableList(), toMtabuleSet(), toMutableMap()을 추가 호출하여 가변 리스트로 변경

가변 컬렉션

  • 삽입, 수정, 삭제 등 변경이 자유로운 컬렉션
  • 가변 컬렉션 (MutableCollection)은 기본인 컬렉션(Collection)을 상속
  • mutableListOf(), mutableSetOf(), mutableMapOf()메소드를 사용하여 컬렉션 객체 생성
    • ArrayList, LinkedList, LinkedHashSet, LikedHashMap, HashMap 등의 컬렉션 클래스들의 생성자 사용 가능
  • 가변컬렉션을 불변 컬렉션으로 재변경을 위해서는 toList(), toSet(), toMap()을 사용

기본 함수

filter

  • 특정 조건에 만족하는 요소만을 추출하여 새로운 컬렉션 생성
val num = listOf(1, 2, 3, 4, 5, 6, 7)
val evenNum = num.filter { it % 2 == 0 }

println(evenNum) // 출력값 : [2, 4, 6]

map

  • 각 요소에 특정 수식을 적용한 결과를 추출하여 새로운 컬렉션 생성
val num = listOf(1, 2, 3)
val squaredNum = num.map { it * it }

println(squaredNum) // 출력값 : [1, 4, 9]

forEach

  • 컬렉션의 각 요소에 대해 특정 작업 수행
val num = listOf(1, 2, 3)
num.forEach { println(it) } 

//출력값 : 
// 1
// 2
// 3

any

  • 컬렉션의 요소 중 하나라도 조건에 만족 시 true
val num = listOf(1, 3)
println(num.any { it % 2 == 0 }) // 출력값 : false 반환

all

  • 컬렉션의 모든 요소가 조건에 만족 시 true 반환
val num = listOf(2, 4, 6)
println(num.all { it % 2 == 0 }) // 출력값 : true 반환

none

  • 컬렉션의 모든 요소가 조건을 모두 만족하지 않을 시 true 반환
val num = listOf(2, 4, 6)
println(num.all { it % 2 != 0 }) // 출력값 : true 반환

중첩 컬렉션 처리

  • 컬렉션 안에 또 다른 컬렉션이 포함된 형태
  • 2차원 배열, 리스트 내부의 리스트, 맵 안에 리스트 등
  • flatten()을 사용하여 중첩리스트를 평탄화 할 수 있음
val nested = listOf(listOf(1, 2), listOf(3, 4))
val flat = nested.flatten() // [1, 2, 3, 4]
  • flatMap()을 사용하여 map과 flatten을 동시에 사용 가능
val words = listOf("hello", "world")
val chars = words.flatMap { it.toList() }
// ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
    • 2차원 배열
    val matrix: Array<IntArray> = arrayOf(
        intArrayOf(1, 2, 3),
        intArrayOf(4, 5, 6),
        intArrayOf(7, 8, 9)
    )
    println(matrix[0][1]) // 출력: 2
  • 리스트 내부의 리스트맵 안에 리스트이중 컬렉션 순회
    for (row in matrix) {
        for (element in row) {
            print("$element ")
        }
        println()
    }

퀴즈

객관식

1. 다음 중 flatMap 함수의 설명으로 옳은 것은?

  1. 리스트 안의 요소들을 역순으로 정렬한다.
  2. 리스트를 평탄화하지만 중복을 제거한다.
  3. 각 요소를 변환하고, 중첩 컬렉션을 평탄화한다.
  4. 모든 요소를 문자열로 변환한다.

답: 3

 

2. 다음 코드의 결과는?

val data = listOf(
    listOf("a", "b"),
    listOf("c", "d")
)

println(data.flatten())
  1. [["a", "b"], ["c", "d"]]
  2. ["a", "b", "c", "d"]
  3. "abcd"
  4. [[a, b, c, d]]

답: 2

 

3. 다음 중 mapValues를 사용하는 목적에 가장 부합하는 것은?

val data = mapOf("A" to listOf(1, 2), "B" to listOf(3, 4))
val result = data.mapValues { it.value.sum() }
  1. 키를 기준으로 정렬하기 위해
  2. 각 값 리스트를 합산하여 새 Map을 만들기 위해
  3. 값이 아닌 키를 변경하기 위해
  4. 리스트를 필터링하기 위해

답: 2

 

더보기

📌 mapValues

Map에서 제공되는 고차함수로 키-값 중 값만 변환

map과의 차이점

  • map: Map이 아니라 List로 바뀜
  • mapValues: Map을 유지하면서 값만 변경

→ 람다와 고차 함수에서 추가학습

서술형

1. 평탄화 및 필터링

다음과 같은 학생들의 시험 점수가 2차원 리스트 형태로 주어졌을 때,

60점 이상인 점수만 추출한 후, 총합을 구하는 코드를 작성하시오.

val scores = listOf(
    listOf(45, 82, 77),
    listOf(59, 90, 100),
    listOf(62, 58, 71)
)

조건: flatten, filter, sum 등의 컬렉션 함수를 사용할 것.

 

답:

scores.flatten().filter{it>=60}.sum()

 

 

2. 중첩된 문자열 처리

다음과 같은 단어 리스트가 있을 때,

모든 단어를 알파벳 단위로 쪼개어 한 리스트로 만든 후, 중복을 제거하고 정렬된 리스트를 반환하는 함수를 작성하시오.

val wordGroups = listOf(
    listOf("apple", "banana"),
    listOf("cherry", "date"),
    listOf("banana", "elderberry")
)

출력 예시: ['a', 'b', 'c', 'd', 'e', 'h', 'l', 'n', 'p', 'r', 'y']

 

답:

wordGroups.flatMap{ it.toList() }.distinct().sort()

→ 오답노트:

wordGrops
	.flatten() // 리스트들을 평탄화
	.flatMap{it.toList()} // 단어들을 쪼개기
	.distinct() // 중복 제거
	.sorted() // 정렬: sort()는 MutableList()에서 사용

 

 

3. 학생별 평균 점수 계산

다음과 같은 Map 구조가 있을 때,

각 학생의 평균 점수를 출력하는 프로그램을 작성하시오.

val studentScores = mapOf(
    "Alice" to listOf(90, 80, 70),
    "Bob" to listOf(100, 90),
    "Charlie" to listOf(60, 65, 70, 75)
)

출력 예시:

Alice: 80.0
Bob: 95.0
Charlie: 67.5

 

답:

for ((name, scores) in studentScores) {
	var avg = scores.average()
	println("$student.key: $avg")
}