lambda function Kotlin


1. 개요
콜백함수를 외부에 만들지 않고 함수를 변수처럼 전달한다.

단일 함수 구현 콜백이 필요한 객체 인스턴스 생성에서 사용, 
SAM (Single Abstract Method) 과 같이 구현대상이 명확한 함수하나만 있는 인터페이스 구현에 사용됨


Thread(object:Runnable{
override fun run() {
}
}).start()


thread {

}.start()

(괄호가 없어지고 {만 생김

2. 콜렉션 객체에서의 람다
콜렉션 객체는 여러 유틸리티 함수를 담고 있는데 심플한 구현을 람다를 활용해 제공

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

fun findTheOldest(people: List<Person>) {
var mx = 0
var mo: Person? = null
for (a in people) {
if (a.age > mx) {
mo = a
mx = a.age
}
}
println(mo)
}

fun a() {
val people = listOf(Person("Alice", 29), Person("Bob", 31))
findTheOldest(people)
}


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

fun b() {
val people = listOf(Person("Alice", 29), Person("Bob", 31))

people.maxBy { it.age }
}
a 함수와 b함수의 결과는 같음

3. 람다의 예시
val sum = { x: Int, y: Int -> x + y }
sum(1, 2) // lambda 함수 호출
println(sum(1, 2))
{ println("welcome") }()
run { println("welcome") }

4. 축약의 단계
val people = listOf(Person("Alice", 29), Person("Bob", 31))
people.maxBy({ p: Person -> p.age })
people.maxBy() { p: Person -> p.age } // 맨 뒤의 인자가 람다식이면 괄호 밖으로, 마지막 람다는 바로 앞 괄호에 입력값으로 쓰임
people.maxBy { p: Person -> p.age }// 람다가 함수의 유일한 인자이면 괄호 생략가능
people.maxBy { p -> p.age }
people.maxBy { it.age }

val getAge = { p: Person -> p.age } // 함수 변수를 사용한 예
people.maxBy(getAge)
5. forEach

fun printMessageWithPrefix(messages: Collection<String>, prefix: String) {
messages.forEach {
println("$prefix $it")
}
}

fun a() {
val errors = listOf("403 Forbidden", "404 Not Found")
printMessageWithPrefix(errors, "Error:")
}

람다 외부 변수에 접근

fun printProblemCounts(responses: Collection<String>) {
var clientErrors = 0
var serverErrors = 0
responses.forEach {
if (it.startsWith("4")) {
clientErrors++
} else if (it.startsWith("5")) {
serverErrors++
}
}
println("$clientErrors client errors, $serverErrors server errors")
}

fun a() {
val responses = listOf("200 OK", "408 I'm a teapot", "500 Internal Server Error")
printProblemCounts(responses)
}

6. filter
조건이 참인 원소로 구성된 콜렉션을 만든다
val list = listOf(1, 2, 3, 4)
println(list.filter { it % 2 == 0 }) // 조건이 참인 것만 골라낸다

val people = listOf(Person("Alice", 29), Person("Bob", 31))
println(people.filter { it.age > 30 })

7. map

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

val list = listOf(1, 2, 3, 4)
println(list.map { it * it }) // 원소값을 변환

val people = listOf(Person("Alice", 29), Person("Bob", 31))
println(people.map { it.name }) // 이름만으로 이뤄진 콜렉션 생성, [Alice, Bob]

people.filter { it.age > 30 }.map { it.name } // [Bob]

val numbers = mapOf(0 to "zero", 1 to "one")
println(numbers.mapValues { it.value.toUpperCase() })
8. all, any 
참/거짓을 반환
모두 조건을 만족하는지 하나라도 조건을 만족하는지

9. count
갯수를 반환
조건에 부합하는 원소의 갯수

컬렉션을 만들고 size를 얻는것보다 효율적이다. 컬렉션을 만들 필요가 없으므로

10. find
조건에 부합하는 원소를 반환, 없으면 null

11. groupBy
멤버에 의해 그룹화된 2중 배열형식 콜렉션을 생성
val people = listOf(Person("Alice", 29), Person("Bob", 31), Person("Carol", 31))
println(people.groupBy { it.age }) // Map<Int, List<Person>>
12. flatMap, flatten
각 원소에 대한 람다 결과 콜렉션간의 merge
val strings = listOf("abc", "def")
println(strings.flatMap { it.toList() }) // [a,b,c,d,e,f]
val books = listOf(Book("Thursday Next", listOf("Jasper Fforde")),
Book("Mort", listOf("Terry Pratchett")),
Book("Good Omens", listOf("Terry Pratchett", "Neil Gaiman")))
println(books.flatMap { it.authors }.toSet()) // ["Jasper Fforde","Terry Pratchett","Neil Gaiman"]
// toSet은 중복을 없앤다
val deepArray = arrayOf(
arrayOf(1),
arrayOf(2, 3),
arrayOf(4, 5, 6)
)

println(deepArray.flatten()) // [1, 2, 3, 4, 5, 6]




덧글

댓글 입력 영역