티스토리 뷰

코틀린 공식문서에 있는 Example들을 하나씩 읽어보며 정리하자.

참고: https://play.kotlinlang.org/byExample/overview

 

 

Collections

List

코틀린의 리스트는 변경가능한 리스트(MutableList)와 읽기전용(read-only) 리스트가 있다.

리스트 생성은 아래와 같다.

  • mutableListOf() : 변경가능한 리스트
  • listOf() : 읽기전용 리스트

원치 않는 수정을 방지하려면 mutableList를 List(read-only)로 변경한다.

val systemUsers: MutableList<Int> = mutableListOf(1, 2, 3)        // 1
val sudoers: List<Int> = systemUsers                              // 2

fun addSystemUser(newUser: Int) {                                 // 3
    systemUsers.add(newUser)                      
}

fun getSysSudoers(): List<Int> {                                  // 4
    return sudoers
}

fun main() {
    addSystemUser(4)                                              // 5 
    println("Tot sudoers: ${getSysSudoers().size}")               // 6
    getSysSudoers().forEach {                                     // 7
        i -> println("Some useful info on user $i")
    }
    // getSysSudoers().add(5) <- Error!                           // 8
}

/*
Tot sudoers: 4
Some useful info on user 1
Some useful info on user 2
Some useful info on user 3
Some useful info on user 4
*/
  1. MutableList를 생성한다.
  2. 읽기전용 List를 생성한다.
  3. MutableList에 새 아이템을 추가한다.
  4. 해당 함수는 변경할 수 없는 List를 리턴한다.
  5. MutableList를 업데이트한다. 관련된 읽기전용 List도 동일한 객체를 가리키므로 업데이트된다.
  6. 읽기 전용 리스트의 사이즈를 조회한다.
  7. 리스트를 반복하고 해당 요소를 출력한다.
  8. 읽기전용 뷰에 쓰기를 시도하면 컴파일 에러가 발생한다.

Set

Set도 아래와 같이 생성한다.

  • mutableSetOf() : 변경가능한 셋
  • setOf() : 읽기전용 셋

mutable set의 읽기전용 뷰는 Set으로 캐스팅하여 얻을 수 있다.

val openIssues: MutableSet<String> = mutableSetOf("uniqueDescr1", "uniqueDescr2", "uniqueDescr3") // 1

fun addIssue(uniqueDesc: String): Boolean {                                                       
    return openIssues.add(uniqueDesc)                                                             // 2
}

fun getStatusLog(isAdded: Boolean): String {                                                       
    return if (isAdded) "registered correctly." else "marked as duplicate and rejected."          // 3
}

fun main() {
    val aNewIssue: String = "uniqueDescr4"
    val anIssueAlreadyIn: String = "uniqueDescr2" 

    println("Issue $aNewIssue ${getStatusLog(addIssue(aNewIssue))}")                              // 4
    println("Issue $anIssueAlreadyIn ${getStatusLog(addIssue(anIssueAlreadyIn))}")                // 5 
}

/*
Issue uniqueDescr4 registered correctly.
Issue uniqueDescr2 marked as duplicate and rejected.
*/
  1. 주어진 요소로 Set을 만든다.
  2. 요소가 실제로 추가되었는지 여부를 나타내는 boolean 값을 리턴한다.
  3.  함수 매개변수를 기반으로 문자열을 리턴한다.
  4. 성공 메세지를 출력하고 새 요소가 Set에 추가된다.
  5. 실패 메세지를 출력하고 중복 요소이기 때문에 추가되지 않는다.

Map

map도 아래와 같이 생성된다.

  • mutableMapOf() : 변경가능한 맵
  • mapOf() : 읽기전용 맵

mutable map의 읽기전용 맵은 Map으로 캐스팅하여 얻을 수 있다.

const val POINTS_X_PASS: Int = 15
val EZPassAccounts: MutableMap<Int, Int> = mutableMapOf(1 to 100, 2 to 100, 3 to 100)   // 1
val EZPassReport: Map<Int, Int> = EZPassAccounts                                        // 2

fun updatePointsCredit(accountId: Int) {
    if (EZPassAccounts.containsKey(accountId)) {                                        // 3
        println("Updating $accountId...")                                               
        EZPassAccounts[accountId] = EZPassAccounts.getValue(accountId) + POINTS_X_PASS  // 4
    } else {
        println("Error: Trying to update a non-existing account (id: $accountId)")
    } 
}

fun accountsReport() {
    println("EZ-Pass report:")
    EZPassReport.forEach {                                                              // 5
        k, v -> println("ID $k: credit $v")
    }
}

fun main() {
    accountsReport()                                                                    // 6
    updatePointsCredit(1)                                                               // 7
    updatePointsCredit(1)                                                               
    updatePointsCredit(5)                                                               // 8 
    accountsReport()                                                                    // 9
}

/*
EZ-Pass report:
ID 1: credit 100
ID 2: credit 100
ID 3: credit 100
Updating 1...
Updating 1...
Error: Trying to update a non-existing account (id: 5)
EZ-Pass report:
ID 1: credit 130
ID 2: credit 100
ID 3: credit 100
*/
  1. mutable Map을 생성한다.
  2. 읽기전용 Map을 생성한다.
  3. Map의 key가 존재하는지 체크한다.
  4. 해당 값을 읽고 상수 값을 증가시킨다.
  5. immutable Map을 반복하고 key/value 쌍을 출력한다.
  6. 업데이트 전에 계정 포인트 잔액을 읽는다.
  7. 기존 계정을 두 번 업데이트한다.
  8. 존재하지 않는 계정 업데이트 시도: 오류 메세지를 출력한다.
  9. 업데이트 후, 계정 포인트 잔액을 읽는다.

filter

filter 함수를 사용하면 컬렉션을 필터링할 수 있다.

filter 함수는 람다로 필터 조건 인자(predicate)를 받는다.

필터 조건 인자(predicate)는 각 요소에 적용된다.

필터 조건 인자(predicate)를 true로 만드는 요소는 결과 컬렉션에 요소로 리턴된다.

val numbers = listOf(1, -2, 3, -4, 5, -6)      // 1

val positives = numbers.filter { x -> x > 0 }  // 2

val negatives = numbers.filter { it < 0 }      // 3

/*
Numbers: [1, -2, 3, -4, 5, -6]
Positive Numbers: [1, 3, 5]
Negative Numbers: [-2, -4, -6]
*/
  1. 숫자 컬렉션을 정의한다.
  2. 양수를 가져온다.
  3. 더 짧은 it 표기법을 사용하여 음수를 가져온다.

map

맵 확장 함수를 사용하면 컬렉션의 모든 요소에 변환기능을 적용할 수 있다. 변환기능은 람다로 받는다.

val numbers = listOf(1, -2, 3, -4, 5, -6)     // 1

val doubled = numbers.map { x -> x * 2 }      // 2

val tripled = numbers.map { it * 3 }          // 3

/*
Numbers: [1, -2, 3, -4, 5, -6]
Doubled Numbers: [2, -4, 6, -8, 10, -12]
Tripled Numbers: [3, -6, 9, -12, 15, -18]
*/
  1. 숫자 컬렉션을 정의한다.
  2. 숫자를 2배한다.
  3. 더 짧은 it 표기법을 사용하여 숫자를 3배로 만든다.

any, all, none

이 컬렉션 함수들은 주어진 조건(predicate)에 일치하는 요소가 존재하는지 체크하는 함수이다.

 

any

any 함수는 컬렉션에 주어진 조건과 일치하는 요소가 하나 이상 포함되어 있으면 true를 리턴한다.

val numbers = listOf(1, -2, 3, -4, 5, -6)            // 1

val anyNegative = numbers.any { it < 0 }             // 2

val anyGT6 = numbers.any { it > 6 }                  // 3

/*
Numbers: [1, -2, 3, -4, 5, -6]
Is there any number less than 0: true
Is there any number greater than 6: false
*/
  1. 숫자 컬렉션을 정의한다.
  2. 음수가 존재하는지 체크한다.
  3. 6보다 큰 요소가 있는지 체크한다.

all

all 함수는 컬렉션의 모든 요소가 주어진 조건과 일치하면 true를 리턴한다.

val numbers = listOf(1, -2, 3, -4, 5, -6)            // 1

val allEven = numbers.all { it % 2 == 0 }            // 2

val allLess6 = numbers.all { it < 6 }                // 3

/*
Numbers: [1, -2, 3, -4, 5, -6]
All numbers are even: false
All numbers are less than 6: true
*/
  1. 숫자 컬렉션을 정의한다.
  2. 모든 요소들이 짝수인지 체크한다.
  3. 모든 요소들이 6보다 작은지 체크한다.

none

none 함수는 컬렉션에 주어진 조건과 일치하는 요소가 하나도 없으면 true를 리턴한다.

(모든 요소가 주어진 조건을 다 만족하지 않아야됨)

val numbers = listOf(1, -2, 3, -4, 5, -6)            // 1

val allEven = numbers.none { it % 2 == 1 }           // 2

val allLess6 = numbers.none { it > 6 }               // 3

/*
Numbers: [1, -2, 3, -4, 5, -6]
All numbers are even: false
No element greater than 6: true
*/
  1. 숫자 컬렉션을 정의한다.
  2. 홀수 요소가 없는지 확인한다. (모든 요소가 짝수)
  3. 6보다 큰 요소가 없는지 확인한다.

find, findLast

find 및 findLast 함수는 주어진 조건과 일치하는 첫번째 또는 마지막 컬렉션 요소를 리턴한다.

그러한 요소가 없으면 null을 리턴한다.

val words = listOf("Lets", "find", "something", "in", "collection", "somehow")  // 1

val first = words.find { it.startsWith("some") }                                // 2
val last = words.findLast { it.startsWith("some") }                             // 3

val nothing = words.find { it.contains("nothing") }                             // 4

/*
The first word starting with "some" is "something"
The last word starting with "some" is "somehow"
The first word containing "nothing" is null
*/

 

  1. 단어 컬렉션을 정의한다.
  2. "some"으로 시작하는 첫 번째 단어를 찾는다.
  3. "some"으로 시작하는 마지막 단어를 찾는다.
  4. "nothing"이 포함된 첫 번째 단어를 찾는다.

first, last

first, last

이 함수는 해당 컬렉션의 첫 번째 및 마지막 요소를 리턴한다.

조건과 함께 이 함수들을 사용하면 주어진 조건에 일치하는 요소 중 첫 번째, 마지막 요소를 리턴한다.

만약 컬렉션이 비어있거나 주어진 조건에 일치하는 요소가 없으면 NoSuchElementException을 발생시킨다.

(조건을 사용하면, find, findLast와 같지만 주어진 조건을 만족하지 않으면 null을 리턴하는가, NoSuchElementException를 발생키는가가 다르다)

val numbers = listOf(1, -2, 3, -4, 5, -6)            // 1

val first = numbers.first()                          // 2
val last = numbers.last()                            // 3

val firstEven = numbers.first { it % 2 == 0 }        // 4
val lastOdd = numbers.last { it % 2 != 0 }           // 5

/*
Numbers: [1, -2, 3, -4, 5, -6]
First 1, last -6, first even -2, last odd 5
*/
  1. 숫자 컬렉션을 정의한다.
  2. 첫 요소를 뽑는다.
  3. 마지막 요소를 뽑는다.
  4. 첫번째 짝수 요소를 뽑는다.
  5. 마지막 홀수 요소를 뽑는다.

firstOrNull, lastOrNull

이 함수는 한 가지 차이점이 있지만 거의 동일한 방식으로 작동한다.

일치하는 요소가 없으면 null을 리턴한다.

val words = listOf("foo", "bar", "baz", "faz")         // 1
val empty = emptyList<String>()                        // 2

val first = empty.firstOrNull()                        // 3
val last = empty.lastOrNull()                          // 4

val firstF = words.firstOrNull { it.startsWith('f') }  // 5
val firstZ = words.firstOrNull { it.startsWith('z') }  // 6
val lastF = words.lastOrNull { it.endsWith('f') }      // 7
val lastZ = words.lastOrNull { it.endsWith('z') }      // 8

/*
Empty list: first is null, last is null
Word list: first item starting with 'f' is foo, first item starting with 'z' is null
Word list: last item ending with 'f' is null, last item ending with 'z' is faz
*/
  1. 단어 컬렉션을 정의한다.
  2. 빈 컬렉션을 정의한다.
  3. 빈 컬렉션에서 첫번째 요소를 선택한다. (=null)
  4. 빈 컬렉션에서 마지막 요소를 선택한다. (=null)
  5. 'f'로 시작하는 첫번째 요소를 선택한다. (=foo)
  6. 'z'로 시작하는 첫번째 요소를 선택한다. (=null)
  7. 'f'로 끝나는 마지막 요소를 선택한다. (=null)
  8. 'z'로 끝나는 마지막 요소를 선택한다. (=faz)

count

count 함수는 컬렉션의 총 요소 수 또는 주어진 조건과 일치하는 요소 수를 리턴한다.

val numbers = listOf(1, -2, 3, -4, 5, -6)            // 1

val totalCount = numbers.count()                     // 2
val evenCount = numbers.count { it % 2 == 0 }        // 3

/*
Total number of elements: 6
Number of even elements: 3
*/
  1. 숫자 컬렉션을 정의한다.
  2. 총 요소 수를 계산한다.
  3. 짝수 요소 수를 계산한다.
링크
최근에 올라온 글
글 보관함
«   2025/10   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31