Chef.Yeon
Code Cook
Chef.Yeon
전체 방문자
오늘
어제
  • 분류 전체보기 (230)
    • 게임 개발 (1)
      • Unity (1)
    • Android (27)
      • Kotlin (19)
      • 우아한테크코스 5기 (4)
    • Language (11)
      • 파이썬 (3)
      • Java (7)
    • DB (2)
      • SQL (16)
    • Spring (25)
    • 코딩테스트 (56)
    • Git (1)
    • TIL (85)
    • DevOps (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 내림차순
  • elasticsearch
  • 에라토스테네스의 체
  • java
  • 프리코스
  • Android
  • SQL
  • 프로그래머스
  • webflux
  • 우아한테크코스
  • ec2
  • 파이썬
  • 문자열
  • rsocket
  • kotlin
  • 코틀린
  • 안드로이드
  • MariaDB
  • enum
  • 다이나믹 프로그래밍
  • Docker
  • 코딩테스트
  • 코틀린 인 액션
  • 백준
  • grafana
  • spring
  • til
  • Wil
  • kibana
  • 레포지토리

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Chef.Yeon

Code Cook

Android/Kotlin

[코틀린 인 액션] 5장 정리

2022. 11. 30. 15:49
728x90
5.1.2 람다와 컬렉션

   1. 라이브러리 함수를 사용하여 프로퍼티를 비교해 값이 가장 큰 원소 찾기

// 루프 사용
class Person(val name: String, val age: Int)

fun main(args: Array<String>) {
    val people = listOf(Person("Alice", 29), Person("Bob", 31))
    findTheOldest(people)
}

fun findTheOldest(people: List<Person>) {
    var maxAge = 0
    var theOldest: Person? = null
    for (person in people) {
        if (person.age > maxAge) {
            maxAge = person.age
            theOldest = person
        }
    }
    println(theOldest?.age)
}

 

   2. 람다를 사용해 컬렉션 검색

fun main(args: Array<String>) {
    val people = listOf(Person("Alice", 29), Person("Bob", 31))
    println(people.maxBy{it.age}.age)
}

 

   3. 멤버 참조를 이용해 컬렉션 검색

fun main(args: Array<String>) {
    val people = listOf(Person("Alice", 29), Person("Bob", 31))
    println(people.maxBy(Person::age).age)
}

 

5.1.3 람다식의 문법

   1. 람다 식을 maxBy 함수에 넘김

people.maxBy({p: Person -> p.age})

    -> 람다를 괄호 밖으로 빼낼 수 있음

 

people.maxBy() {p: Person -> p.age}

   -> 괄호 뒤에 람다가 썼다면 호출 시 빈 괄호를 없애도 됨

 

people.maxBy{p: Person -> p.age}

 

   2. joinToString에 람다 사용

// 이름 붙인 인자를 사용해 람다 넘기기
class Person(val name: String, val age: Int)

fun main(args: Array<String>) {
    val people = listOf(Person("Alice", 29), Person("Bob", 31))
    val names = people.joinToString(separator = " ", transform = { p: Person -> p.name })
    println(names)
}

 

// 람다를 괄호 밖에 전달
fun main(args: Array<String>) {
    val people = listOf(Person("Alice", 29), Person("Bob", 31))
    val names = people.joinToString(separator = " ") { p: Person -> p.name }
    println(names)
}

 

   3. 람다의 파라미터 타입을 생략해도 컴파일러가 추론

people.maxBy{p -> p.age}

 

   4. 람다의 파라미터가 하나뿐이고, 그 타입을 컴파일러가 추론할 수 있는 경우 it 사용 가능

people.maxBy{it.age}

 

5.1.5 멤버 참조

   1. 람다를 이용해 넘기려는 코드가 이미 함수로 선언된 경우, 함수를 직접 넘길 수 있음

     - 이중 콜론(::) 사용

     - run은 인자로 받은 람다를 실행

 

   2. 멤버 참조는 최상위 선언된 함수나 프로퍼티 참조 가능

fun main(args: Array<String>) {
    run(::salute) // 최상위 함수 참조
}

fun salute() = println("Salute")

 

   3. 람다가 인자가 여럿인 다름 함수에게 작업을 위임하는 경우, 직접 위임 함수에 대한 참조를 제공 가능

data class Person(val name: String, val age: Int)

fun main(args: Array<String>) {
    val action = { person: Person, message: String ->
        sendEmail(person, message)
    }
    action(Person("Alice",31), "Hello!")
    action(Person("Bob",20), "Bye!")
}

fun sendEmail(person: Person, message: String) {
    println("${person.name}에게 전송할 메시지: $message")
}

 

   4. 생성자 참조를 사용하면 클래스 생성 작업 연기/저장 가능

data class Person(val name: String, val age: Int)

fun main(args: Array<String>) {
    val createPerson = ::Person
    val p = createPerson("Alice",31)
    println(p)
}

 

5.2.1 필수적인 함수: filter와 map

   1. map: 주어진 람다를 컬렉션의 각 원소에 적용한 결과를 모아서 새 컬렉션을 생성

data class Person(val name: String, val age: Int)

fun main(args: Array<String>) {
    val people = listOf(Person("Alice", 31), Person("Bob", 21))
    println(people.map { it.name })
}

 

data class Person(val name: String, val age: Int)

fun main(args: Array<String>) {
    val people = listOf(Person("Alice", 31), Person("Bob", 21))
    println(people.filter { it.age > 30 }.map (Person::name))
}

 

   2. filter와 map을 맵에 적용

fun main(args: Array<String>) {
    val numbers = mapOf(0 to "zero", 1 to "one")
    println(numbers.mapValues { it.value.uppercase() })
}

 

5.2.4 flatMap과 flatten: 중첩된 컬렉션 안의 원소 처리

   1. flatMap: 인자로 주어진 람다를 컬렉션의 모든 객체에 적용하고,
      람다를 적용한 결과 얻어지는 리스트들을 한 리스트로 모음

fun main(args: Array<String>) {
    val strings = listOf("가나다","라마바")
    println(strings.flatMap { it.toList() })
}

 

 

fun main(args: Array<String>) {
    val ls = listOf("가나다", "라마바")
    val map = ls.map{it.toList()}
    println("map: $map")

    val flatten = map.flatten()
    println("flatten: $flatten")
}

   -> flatMap은 map -> flatten 동작과 같음

 

5.3 지연 계산(lazy) 컬렉션 연산
fun main(args: Array<String>) {
    val people = listOf(Person("Alice", 31), Person("Bob", 21))
    val person = people.map(Person::name).filter { it.startsWith("A") }
    println(person)
}

   -> filter와 map은 모두 리스트를 반환하므로 위 연쇄 호출은 리스트를 2개 만들게 됨 (비효율적)

 

   1. 시퀀스를 사용하면 중간 임시 컬렉션을 사용하지 않고 컬렉션 연산을 연쇄할 수 있음

fun main(args: Array<String>) {
    val people = listOf(Person("Alice", 31), Person("Bob", 21))
    val person =people.asSequence()
        .map(Person::name)
        .filter { it.startsWith("A") }
        .toList()
    println(person)
}

 

5.5.1 with 함수
fun alphabet() :String {
    val result = StringBuilder()
    for (letter in 'A'..'Z'){
        result.append(letter)
    }
    result.append("\nNow I Know the alphabet!")
    return result.toString()
}

   -> result에 대해 다른 여러 메서드를 호출하며 매번 result를 반복

 

   1. with함수는 첫 번째 인자로 받은 객체를 두 번째 인자로 받은 람다의 수신 객체로 만듦

     - 람다의 본문에서는 this와 점(.)을 사용하지 않고 프로퍼티나 메서드 이름만 사용해도 수신 객체의 멤버에 접근 가능

fun alphabet() :String {
    val stringBuilder = StringBuilder()
    return with(stringBuilder) {
        for (letter in 'A'..'Z'){
            this.append(letter) // this 생략 가능
        }
        append("\nNow I Know the alphabet!")
        this.toString()
    }
}

 

   2. with와 식을 본문으로 하는 함수를 활용하여 불필요한 stringBuilder 변수 제거 가능

fun alphabet() = with(StringBuilder()) {
    for (letter in 'A'..'Z'){
        append(letter)
    }
    append("\nNow I Know the alphabet!")
    toString()
}

 

5.5.2 apply 함수

   1. with함수와 비슷하지만, apply는 항상 자신에게 전달된 객체를 반환함

 

   2. 객체의 인스턴스를 만들면서 즉시 프로퍼티 중 일부를 초기화해야 하는 경우 유용함

fun alphabet() = StringBuilder().apply {
    for (letter in 'A'..'Z'){
        append(letter)
    }
    append("\nNow I Know the alphabet!")
}.toString()

 

   3. 표준 라이브러리의 buildString 함수를 사용하면 StringBuilder 객체 생성과, toString 호출을 알아서 해줌

fun alphabet() = buildString {
    for (letter in 'A'..'Z'){
        append(letter)
    }
    append("\nNow I Know the alphabet!")
}
728x90

'Android > Kotlin' 카테고리의 다른 글

[코틀린 인 액션] 7장 정리: 연산자 오버로딩  (0) 2022.12.05
[코틀린 인 액션] 6장 정리: null 다루는 방법  (0) 2022.11.30
[코틀린 인 액션] 4장 정리  (0) 2022.11.29
[코틀린 인 액션] 3장 정리  (0) 2022.11.28
[코틀린 인 액션] 2장 정리  (0) 2022.11.24
    'Android/Kotlin' 카테고리의 다른 글
    • [코틀린 인 액션] 7장 정리: 연산자 오버로딩
    • [코틀린 인 액션] 6장 정리: null 다루는 방법
    • [코틀린 인 액션] 4장 정리
    • [코틀린 인 액션] 3장 정리
    Chef.Yeon
    Chef.Yeon
    보기 좋고 깔끔한 코드를 요리하기 위해 노력하고 있습니다.

    티스토리툴바