10
10

 

๋žŒ๋‹ค ์‹๊ณผ ๋ฉค๋ฒ„์ฐธ์กฐ

๋žŒ๋‹ค์˜ ์˜๋ฏธ๋ฅผ ๋ณด๋ฉด ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ๋„˜๊ธธ ์ˆ˜ ์žˆ๋Š” ์ž‘์€ ์ฝ”๋“œ ์กฐ๊ฐ์ด๋ผ๊ณ  ๋˜์–ด์žˆ๋‹ค. ๋žŒ๋‹ค ์‹์ด๋ผ๊ณ ๋„ํ•˜๊ณ  ํด๋กœ์ €, ๋ฌด๋ช…ํ•จ์ˆ˜, ํ•จ์ˆ˜๋ฆฌํ„ฐ๋Ÿด ๋“ฑ ๋ถ€๋ฅด๋Š” ์ด๋ฆ„์ด ๋งŽ์€๋ฐ, ์•ˆ๋“œ๋กœ์ด๋“œ๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์‹œ๋„๋•Œ๋„ ์—†์ด ์ถœ๋ชฐํ•œ๋‹ค. ์ผ์ข…์˜ ํ•จ์ˆ˜๊ฐ’์„ ๋„˜๊ธด๋‹ค๊ณ  ๋ณผ ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, ์ฝ”ํ‹€๋ฆฐ์ด ํ•จ์ˆ˜๋„ ํƒ€์ž…์œผ๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ผ ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋žŒ๋‹ค๋Š” ์ž๋ฐ”์˜ ๋ฌด๋ช…๋‚ด๋ถ€ ํด๋ž˜์Šค, ๋‹จ์ผ ๋ฌด๋ช… ๊ฐ์ฒด๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Š” setOnClickListener๋งŒ ๋ด๋„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

๋žŒ๋‹ค์‹์€ ์ปฌ๋ ‰์…˜์ด๋‚˜ String๊ฐ์ฒด ๊ฐ™์€ ๊ณณ์—๋„ ์ž˜ ์‚ฌ์šฉ๋œ๋‹ค.

people.maxBy{it.age}
 

people์€ age, name ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด์ธ๋ฐ, age๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ตœ๋Œ€๊ฐ’์„ ์ฐพ๋Š” ์ฝ”๋“œ๋‹ค. it์ด ๊ฐ€๋ฆฌํ‚ค๋Š”๊ฑด ์ปฌ๋ ‰์…˜์˜ ์›์†Œ๋‹ค. ์ฝ”ํ‹€๋ฆฐ์˜ ๋žŒ๋‹ค ์‹์€ ํ•ญ์ƒ ์ค‘๊ด„ํ˜ธ๋กœ ๋ฌถ์—ฌ์žˆ๋‹ค.

๋žŒ๋‹ค ์‹

val sum = {x: Int, y: Int -> x + y}
 

x,y๋ฅผ ์ธ์ž๋กœ ํ•˜๋Š” ํ•จ์ˆ˜๋‹ค. sum(1, 2)๋กœ ํ˜ธ์ถœํ•˜๋ฉด 3์ด ๋ฐ˜ํ™˜๋œ๋‹ค. ๋žŒ๋‹ค ์‹์ด ์ผ๋ฐ˜ํ•จ์ˆ˜๊ฐ€ ๋œ ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋žŒ๋‹ค ์‹์„ {์‹ ๋‚ด์šฉ}()ํ˜•ํƒœ๋กœ ํ˜ธ์ถœ ํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, ๊ทธ๋ƒฅ run๋ธ”๋ก์œผ๋กœ ๋‘˜๋Ÿฌ์Œ“์•„์„œ ๋žŒ๋‹ค์‹์„ ์„ ์–ธํ•˜๋ฉด ๋ฐ”๋กœ ์‹คํ–‰๊ฐ€๋Šฅํ•˜๋‹ค. ์ผ๋ฐ˜ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ์‹œ ์Šคํƒ์„ ์Œ“๋Š” ๋ฐ ๋น„ํ•ด ๋žŒ๋‹ค ํ˜ธ์ถœ์€ ๋ถ€๊ฐ€๋น„์šฉ์ด ๋“ค์ง€ ์•Š๋Š”๋‹ค. ๋‹ค์‹œ maxBy๋กœ ๋Œ์•„๊ฐ€์„œ,

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

๋ชจ๋‘ ๋™์ผํ•œ ๋™์ž‘์„ ํ•œ๋‹ค. ํ•จ์ˆ˜ ๋งˆ์ง€๋ง‰ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋žŒ๋‹ค์‹์ด๋ผ๋ฉด ๊ด„ํ˜ธ ๋ฐ–์œผ๋กœ ๋บ„ ์ˆ˜ ์žˆ๋Š” ๊ด€์Šต์ด ์žˆ๊ณ , ๋žŒ๋‹ค ํŒŒ๋ผ๋ฏธํ„ฐ์— ์ด๋ฆ„์„ ๋ถ™์—ฌ์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋‹จ์ผ ํŒŒ๋ผ๋ฏธํ„ฐ๋ผ๋ฉด ๊ด„ํ˜ธ๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๊ณ , ๋žŒ๋‹ค ์ธ์ž๋Š” ํƒ€์ž… ์ถ”๋ก ์ด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ it์ด ๊ธฐ๋ณธ์ด๋‹ค. ๋˜ ์—ฌ๋Ÿฌ์ค„๋กœ ์ด๋ค„์ง„ ๋žŒ๋‹ค์‹์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ์žˆ๋Š” ์‹์ด๋‹ค.

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

๋ฉ”์„œ๋“œ์˜ ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ๋žŒ๋‹ค ์•ˆ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋žŒ๋‹ค ์•ˆ์—์„œ ๋žŒ๋‹ค ๋ฐ”๊นฅ์˜ ๋ณ€์ˆ˜๊ฐ’์„ ๋ฐ”๊ฟ€ ์ˆ˜๋„ ์žˆ์–ด์„œ ํŒŒ์ด๋„์ธ ์™ธ๋ถ€ ๊ฐ’์—๋งŒ ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ๋Š” ์ž๋ฐ”์˜ ๋ฌด๋ช… ๋‚ด๋ถ€ ํด๋ž˜์Šค ๋ณด๋‹ค ์ž์œ ๋กญ๋‹ค. ์ด์™€ ๊ฐ™์ด ๋žŒ๋‹ค ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์™ธ๋ถ€ ๋ณ€์ˆ˜๋ฅผ ํฌํšํ•œ ๋ณ€์ˆ˜๋ผ๊ณ  ํ•˜๋Š”๋ฐ, ํฌํš๋œ ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜ ์‚ฌ์šฉ์ด ๋๋‚˜๋„ ๋žŒ๋‹ค๋ฅผ ๋”ฐ๋กœ ์ €์žฅํ•ด๋’€๋‹ค๋ฉด ํ•ด๋‹น ๋ณ€์ˆ˜์— ์ ‘๊ทผํ• ์ˆ˜์žˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ๋žŒ๋‹ค๋ฅผ ์ €์žฅํ•  ๋•Œ ํฌํšํ•œ ๋ณ€์ˆ˜์™€ ๊ฐ™์ด ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ •ํ™•ํžˆ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํฌํšํ•œ ๋ณ€์ˆ˜๋งˆ๋‹ค ๊ทธ ๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ํ•„๋“œ๋ฅผ ๋งŒ๋“ ๋‹ค.

๋ฉค๋ฒ„ ์ฐธ์กฐ

๋žŒ๋‹ค๋Š” ํ•จ์ˆ˜์˜ ๋ฐ”๋””๋งŒ ๋–ผ์„œ ๋ณด๋Š”๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿผ ์ด๋ฏธ ์ •์˜ ๋œ ํ•จ์ˆ˜๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ธฐ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ๋ ๊นŒ? ์ด๋•Œ :: ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ด ๋ฐฉ์‹์„ ๋ฉค๋ฒ„ ์ฐธ์กฐ๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, ํด๋ž˜์Šค์— ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ(ํ™•์žฅํ•จ์ˆ˜ ํฌํ•จ) ๋‹จ ํ•˜๋‚˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜๊ฐ’์„ ๋งŒ๋“ค์–ด์ค€๋‹ค.

people.maxBy{person: Person -> person.age}
people.maxBy(Person::age)
run(::superior)
 

๊ฐ™์€ ๋‚ด์šฉ์„ ๋ฉค๋ฒ„ ์ฐธ์กฐ๋กœ ๋ฐ”๊พผ ๋ชจ์Šต์ด๋‹ค. ๋ฉค๋ฒ„ ์ฐธ์กฐ ๋’ค์— ๊ด„ํ˜ธ๊ฐ€ ์—†๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๊ณ , ํƒ€์ž…์ด ํ•ด๋‹น ๋ฉค๋ฒ„๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋žŒ๋‹ค์™€ ๊ฐ™์•„์„œ ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค(ETA ๋ณ€ํ™˜). ์ตœ์ƒ์œ„ ๋ฉค๋ฒ„๋„ ํ˜ธ์ถœ๊ฐ€๋Šฅํ•œ๋ฐ ํด๋ž˜์Šค๋ฅผ ์ฐธ์กฐ ํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ๋ฉค๋ฒ„๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด ๋ฐฉ์‹์œผ๋กœ ์ƒ์„ฑ์ž ์ฐธ์กฐ๋„ ๊ฐ€๋Šฅํ•œ๋ฐ, ::ํด๋ž˜์Šค์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋ฉด ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ๊ฐ€ ๋œ๋‹ค.

๋ฐ”์šด๋“œ ๋ฉค๋ฒ„ ์ฐธ์กฐ

์ด๊ฑฐ๋Š” ์•ฝ๊ฐ„ ์‹ ๊ธฐํ•œ ๊ธฐ๋Šฅ์ด๋‹ค. ์ด์ „ ์ธ์Šคํ„ด์Šค๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ๋ฒ•์ธ๋ฐ,

fun main(args: Array<String>) {
    val createPerson = ::Person
    var p = createPerson("Alice", 29)
    val getAge = Person::age
    println(getAge(p))
    p = p.copy(name = "Bob", age = 40)
    val bounded = p::age
    println(bounded())
}
 

์ด๋ฏธ ์ƒ์„ฑํ•œ p์ธ์Šคํ„ด์Šค๋ฅผ bounded๊ฐ€ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.

์ปฌ๋ ‰์…˜ API

์ง€๊ธˆ๊นŒ์ง€ ์ž˜ ๋ชจ๋ฅด๊ณ  ์‚ฌ์šฉํ–ˆ๋˜ ์ปฌ๋ ‰์…˜์˜ ํ•จ์ˆ˜ํ˜• API๋“ค์„ ์‚ดํŽด๋ณด๊ฒ ๋‹ค.

filter, map

val list = listOf(1, 2, 3, 4)
println(list.filter { it % 2 == 0 })
println(list.map { it * it })
val numbers = mapOf(0 to "zero", 1 to "one")
println(numbers.mapValues { it.value.toUpperCase() })
 

filter๋Š” ์ปฌ๋ ‰์…˜์„ ๋Œ๋ฉด์„œ ๋žŒ๋‹ค๊ฐ€ true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์›์†Œ๋งŒ ๊ณ ๋ฅธ๋‹ค. ์ฐธ/๊ฑฐ์ง“์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ˆ ์–ด(predicate)๋ผ๊ณ  ํ•˜๋Š”๋ฐ ์œ„ ์ฝ”๋“œ์—์„œ๋Š” {it%2==0}์ด ์ˆ ์–ด๋‹ค. filter๊ฐ€ํ•˜๋Š” ์—ญํ• ์€ ๋‹จ์ง€ ์กฐ๊ฑด์— ๋งž์ถฐ ๊ฑธ๋Ÿฌ๋‚ด๋Š” ๊ฒƒ์ด๊ณ , ๊ฑธ๋Ÿฌ๋‚ธ๊ฐ’/ ๋˜๋Š” ์ดํ„ฐ๋ ˆ์ด์…˜ํ•˜๋ฉด์„œ ๊ฐ’์— ์ผ๊ด„์ ์œผ๋กœ ๋ญ”๊ฐ€ ์กฐ์ž‘์„ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด map์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

map์€ ๊ฐ ์›์†Œ์— ํ•˜๊ณ ์žํ•˜๋Š” ์—ฐ์‚ฐ์„ ์ ์šฉํ•ด ์ƒˆ ์ปฌ๋ ‰์…˜์„ ๋งŒ๋“ ๋‹ค.

println(numbers.mapValues { it.value.toUpperCase() }.hashCode())
println(numbers.hashCode())
 

ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ์ฐ์–ด๋ณด๋ฉด ๋‹ค๋ฅธ ์ปฌ๋ ‰์…˜์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. mapValues, mapKeys, filterKeys, filterValues์™€ ๊ฐ™์€ api๋„ ์กด์žฌํ•ด์„œ, key-value ์Œ์ธ ๋งต ์ž๋ฃŒ๊ตฌ์กฐ์—๋„ ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

all, any, count, find

all๊ณผ any๋Š” ์ปฌ๋ ‰์…˜์˜ ๋ชจ๋“  ์›์†Œ์— ๋Œ€ํ•œ ์กฐ๊ฑด์„ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค. all์€ ๋ชจ๋“  ์›์†Œ๊ฐ€ ๋งŒ์กฑํ•˜๋Š”์ง€, any๋Š” ํ•˜๋‚˜๋ผ๋„ ์›ํ•˜๋Š” ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์ง€ ๊ฒ€์‚ฌ ํ•  ์ˆ˜์žˆ๋‹ค. ๊ฐ€๋…์„ฑ์„ ๋†’์ด๋ ค๋ฉด any๋‚˜ all์— !๋ฅผ ๋ถ™์ด๋Š” ํ–‰์œ„๋ฅผ ์ง€์–‘ํ•˜๋ฉด ๋” ์ข‹๋‹ค. count๋Š” ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์›์†Œ ๊ฐœ์ˆ˜, find๋Š” ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค(null์ด ๋‚˜์˜ค๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค๋ฉด firstOnNull()์ด ๊ฐ€๋…์„ฑ ์ธก๋ฉด์—์„œ ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ผ ์ˆ˜ ์žˆ๋‹ค.). ํŠนํžˆ count๋Š” ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์›์†Œ ๊ฐœ์ˆ˜๋งŒ์„ ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— filter์— size๋ฅผ ๋ถ™์ด๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ€๋ณ๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

println(!list.all { it == 3 })
println(list.any { it != 3 })
println(list.count { it != 3 })
val numberThree = { it == 3 }
println(list.find(numberThree))
 

์œ„ ํ•จ์ˆ˜๋“ค์ด ๊ณ ์ฐจํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์ˆ ์–ด๋ฅผ ๋žŒ๋‹ค ๋ณ€์ˆ˜๋กœ ์ €์žฅํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

groupBy

์ปฌ๋ ‰์…˜์˜ ๋ชจ๋“  ์›์†Œ๋ฅผ ์–ด๋–ค ๊ธฐ์ค€์— ๋”ฐ๋ผ ๊ทธ๋ฃนํ™” ํ•ด์•ผํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

val list = listOf("a", "ab", "b")
println(list.groupBy(String::first))
 

๋ฐ˜ํ™˜๋œ ์ปฌ๋ ‰์…˜์€ Map์ด๋‹ค.

flatMap, flatten

์ด ๋‘ ํ•จ์ˆ˜๋Š” ์ค‘์ฒฉ๋œ ์ปฌ๋ ‰์…˜ ๋‚ด๋ถ€์˜ ์›์†Œ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. flat์œผ๋กœ ๊ฐ’์„ ๋‹ค ๋ถ„๋ฆฌํ•ด ๋‹จ์ผ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š”๋ฐ, ์œ„์—์„œ ์‚ฌ์šฉ๋œ map{}๊ณผ ์ค‘์ฒฉ๋œ ์ปฌ๋ ‰์…˜์„ ํ”ผ๋Š” flat์ด ๊ฐ™์ด ์žˆ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ๋˜๊ฒ ๋‹ค. map์œผ๋กœ ๋ณ€ํ™˜ํ•  ๋‚ด์šฉ์ด ์—†๋‹ค๋ฉด ๊ทธ๋ƒฅ flatten์œผ๋กœ ์ค‘์ฒฉ๋œ ๊ฑธ ํŽผ์น  ์ˆ˜ ์žˆ๋‹ค.

println(books.flatMap { it.authors }.toSet())
println(books.flatten())
 

list๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๋ณต๊ฐ’์„ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์œ„ ์ฝ”๋“œ์™€ ๊ฐ™์ด toSet()๊ฐ™์€ ์กฐ์ž‘์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฒˆ ์ ˆ์—์„œ๋Š” ์• ๋งคํ–ˆ๋˜ ๊ฐœ๋…์„ ์žก์€ ๊ฒƒ๋„ ์žˆ์ง€๋งŒ, ๊ฐœ์ธ์ ์œผ๋กœ๋Š” ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์ค€๋น„ ํ•  ๋•Œ ์•„์ฃผ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ํ•จ์ˆ˜๋ชฉ๋ก์„ ์•Œ๊ฒŒ ๋ผ์„œ ์ข‹์•˜๋‹ค.

์‹œํ€€์Šค์˜ ์ง€์—ฐ ์—ฐ์‚ฐ

์•ž์—์„œ ์žˆ๋˜ ์ปฌ๋ ‰์…˜ ํ•จ์ˆ˜๋“ค์€ ์ฆ‰์‹œ ์—ฐ์‚ฐ๋œ๋‹ค. ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ๋Š” ๋งค ๋‹จ๊ณ„๋งˆ๋‹ค ์ค‘๊ฐ„ ์—ฐ์‚ฐ๊ฒฐ๊ณผ๋ฅผ ์ž„์‹œ ์ €์žฅํ•˜๋Š” ๋ฐ, ์‹œํ€€์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ทธ๊ฑธ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

listOf(1, 2, 3, 4).asSequence()
            .map { print("map($it) "); it * it }
            .filter { print("filter($it) "); it % 2 == 0 }
            .toList()
 

asSequence()๋ฅผ ์‚ฌ์šฉํ•ด ์‹œํ€€์Šค๋กœ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฌถ์–ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ํšจ์œจ์ด ์˜ฌ๋ผ๊ฐ„๋‹ค. ์‹œํ€€์Šค๋„ ์ปฌ๋ ‰์…˜๊ณผ ๋™์ผํ•œ API๋ฅผ ์ œ๊ณตํ•ด์„œ ์‚ฌ์šฉ์— ๋‹ฌ๋ผ์ง€๋Š” ๊ฑด ์—†๋‹ค. ๋‹ค๋งŒ ์‹œํ€€์Šค์—์„œ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ์ด์šฉํ•ด ์ฐจ๋ก€๋Œ€๋กœ ์กฐ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ฑ์Šค๋ฅผ ๋”ฐ๋กœ ์ง€์ •ํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๋Š” List๋กœ ๋‹ค์‹œ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•œ๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ toList()๊ฐ€ ์ตœ์ข…์—ฐ์‚ฐ, ๊ทธ ์‚ฌ์ด์— ์žˆ๋Š” ๊ฒŒ ์ค‘๊ฐ„์—ฐ์‚ฐ์ด๋‹ค. ์‹œํ€€์Šค๋ฅผ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, ํŠน์ • ์—ฐ์‚ฐ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์‹œํ€€์Šค๋ฅผ ๋งŒ๋“ค๋•Œ generateSequence๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

fun File.isInsideHiddenDirectory() =
        generateSequence(this) { it.parentFile }.find { it.isHidden }

fun main(args: Array<String>) {
    val file = File("/Users/username/.HiddenDir/a.txt")
    println(file.isInsideHiddenDirectory())
}
 

์œ„์™€ ๊ฐ™์ด ์–ด๋–ค ๊ฐ์ฒด์˜ ์กฐ์ƒ์ด ์ง€๊ธˆ ์ฐพ์„ ๊ฐ’๊ณผ ๊ฐ™์€ ํƒ€์ž…์ด๊ณ , ๋ชจ๋“  ์กฐ์ƒ์˜ ์‹œํ€€์Šค์—์„œ ์–ด๋–ค ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๊ฒฐ๊ณผ ๊ฐ’์ด ํ•„์š”ํ•  ๋•Œ๊ฐ€ ์ผ๋ฐ˜์ ์ธ ์šฉ๋ก€๋‹ค.

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค - SAM

setOnClickListener๊ฐ€ ์ด๋ฒˆ์—๋„ ์˜ˆ์‹œ๋กœ ๋‚˜์˜จ๋‹ค. ์ž๋ฐ”์—์„œ๋Š” ๋ฌด๋ช… ์ธ์Šคํ„ด์Šค๋ฅผ ์ด์šฉํ•ด onClick(View v )๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•ด์„œ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, ์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” ๊ทธ๋ƒฅ ๋žŒ๋‹ค๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋žŒ๋‹ค์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ view๋กœ ๊ทธ๋ƒฅ ์žกํžˆ๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๊ฑด OnClickListener์— ์ถ”์ƒ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹จ ํ•˜๋‚˜๋งŒ ์žˆ๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋‹ค๋ฅธ๋ง๋กœ SAM ์ธํ„ฐํŽ˜์ด์Šค(๋‹จ์ผ ์ถ”์ƒ ์ธํ„ฐํŽ˜์ด์Šค, Single Abstract Method)๋ผ๊ณ  ํ•œ๋‹ค. Runnable, Callable ํƒ€์ž…์ด SAM์— ํ•ด๋‹นํ•˜๋Š”๋ฐ ์ฝ”ํ‹€๋ฆฐ์€ ์—ฌ๊ธฐ์— ๋žŒ๋‹ค๋ฅผ ๋„ฃ์–ด ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋žŒ๋‹ค๋ฅผ ๋ฌด๋ช…ํด๋ž˜์Šค์™€ ์ธ์Šคํ„ด์Šค๋กœ ๋งŒ๋“ค์–ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ด๊ฑด ์ž๋ฐ”์˜ ๊ฒฝ์šฐ๊ณ , ์ฝ”ํ‹€๋ฆฐ inline์œผ๋กœ ํ‘œ์‹œ๋œ ํ•จ์ˆ˜์— ๋žŒ๋‹ค๋ฅผ ๋„˜๊ธฐ๋ฉด ๋ฌด๋ช… ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์ง€์•Š๊ณ  ์ฒ˜๋ฆฌ๋œ๋‹ค.

SAM ์ƒ์„ฑ์ž

fun createAllDoneRunnable(): Runnable {
    return Runnable { println("All done!") }
}

fun main(args: Array<String>) {
    createAllDoneRunnable().run()
}
 

SAM ์ƒ์„ฑ์ž๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ๋ฌด๋ช…ํด๋ž˜์Šค๋กœ ๋žŒ๋‹ค๋ฅผ ๋ฐ”๊ฟ€์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๋‚˜ ์–ด๋–ค ํƒ€์ž…์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์„ ํƒํ•ด ๋žŒ๋‹ค๋ฅผ ๋„˜๊ธธ์ง€ ๋ชจํ˜ธํ•œ ๊ฒฝ์šฐ์— ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ„ ์ฝ”๋“œ๋Š” ์‚ฌ์šฉํ•  ๋žŒ๋‹ค๋ฅผ SAM ์ƒ์„ฑ์ž๋กœ ๊ฐ์‹ผ ๊ฒƒ์ด๋‹ค.

์ˆ˜์‹ ๊ฐ์ฒด ์ง€์ • ๋žŒ๋‹ค: with, apply

์ˆ˜์‹ ๊ฐ์ฒด๋ฅผ ๋ช…์‹œํ•˜์ง€์•Š๊ณ  ๋žŒ๋‹ค ๋ธ”๋Ÿญ์•ˆ์—์„œ ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ๊ฒŒํ•˜๋Š” ํ•จ์ˆ˜๋“ค์ด๋‹ค.

with

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

with()์— ์‚ฌ์šฉํ•  ์ˆ˜์‹ ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•˜๋ฉด ํ•ด๋‹น ์Šค์ฝ”ํ”„ ์•ˆ์—์„œ๋Š” ๋”ฐ๋กœ ์ˆ˜์‹ ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•˜์ง€์•Š์•„๋„ ์ •ํ•ด์ง„ ์ˆ˜์‹ ๊ฐ์ฒด๋ฅผ ๋”ฐ๋ฅธ๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ๋Š” StringBuilder์ธ์Šคํ„ด์Šค๋ฅผ ์ˆ˜์‹ ๊ฐ์ฒด๋กœ ๋„ฃ์—ˆ๋‹ค. ์ค‘๋ณต๋œ ์ด๋ฆ„์ด ์žˆ๋‹ค๋ฉด this๋กœ ์ง€์ •ํ•˜๋Š” ๋ฒ•๋„ ์žˆ๋‹ค. ์ค‘์ฒฉ๋œ with์ด ์žˆ๋‹ค๋ฉด this@์œ„์น˜ํ•œํด๋ž˜์Šค.์‚ฌ์šฉํ• ํ•จ์ˆ˜()๋กœ ์ง€์ •ํ•˜๋ฉด ๋œ๋‹ค.

with์€ ์ด๋ ‡๊ฒŒ ๋žŒ๋‹ค์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , with ๋งˆ์ง€๋ง‰ ์ค„์— ์žˆ๋Š” ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋žŒ๋‹ค์˜ ๊ฒฐ๊ณผ๊ฐ€ ์•„๋‹ˆ๋ผ ์ˆ˜์‹ ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ applyํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

apply

apply๊ฐ€ with๊ณผ ๋‹ค๋ฅธ์ ์€ ์ž์‹ ์—๊ฒŒ ์ „๋‹ฌ๋œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

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

apply๋ฅผ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ๊ฐ€ StringBuilder๊ฐ์ฒด๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ์— toString์„ ๋ฐ–์œผ๋กœ ๋นผ์•ผํ•œ๋‹ค. ์ด์ฒ˜๋Ÿผ apply๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ํ”„๋กœํผํ‹ฐ ์ค‘ ์ผ๋ถ€๋ฅผ ์ดˆ๊ธฐํ™”ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•˜๋‹ค. ์•ˆ๋“œ๋กœ์ด๋“œ์— ๋Œ€์ž…ํ•ด๋ณด๋ฉด RecyclerView์ข…๋ฅ˜๊ฐ€ ์‚ฌ์šฉ๋  ๋•Œ Adapter๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๊ฒ ๋‹ค.

StringBuilder()์™€ toString()์„ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ˆ˜์‹ ๊ฐ์ฒด๋ฅผ StringBuilder๋กœ ์ง€์ •ํ•ด์ค€ buildString ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

fun alphabet() = buildString {
    for (letter in 'A'..'Z') {
        append(letter)
    }
    append("\nNow I know the alphabet!")
}โ€‹
"๋Œ“๊ธ€, ๊ณต๊ฐ ๋ฒ„ํŠผ ํ•œ ๋ฒˆ์”ฉ ๋ˆ„๋ฅด๊ณ  ๊ฐ€์ฃผ์‹œ๋ฉด ํฐ ํž˜์ด ๋ฉ๋‹ˆ๋‹ค"
๋ฐ˜์‘ํ˜•

'๐Ÿ“–๐Ÿ–‹๏ธ > ์ฝ”ํ‹€๋ฆฐ ์ธ ์•ก์…˜๐Ÿ“–' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Kotlin in action(7)  (0) 2023.10.10
Kotlin in action(6)  (0) 2023.10.10
Kotlin in action(4)  (0) 2023.10.10
Kotlin in action(3)  (0) 2023.10.10
Kotlin in action(2)  (0) 2023.10.10
COMMENT