๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

kotlin

[Kotlin] Sequence๋ฅผ ์ด์šฉํ•œ ์ปฌ๋ ‰์…˜ ์ง€์—ฐ ๊ณ„์‚ฐ, ํ•ญ์ƒ ํšจ์œจ์ ์ผ๊นŒ?

๐Ÿ‘€ ์ปฌ๋ ‰์…˜ ํ•จ์ˆ˜๋ฅผ ์—ฐ์‡„ํ•˜๋Š” ๊ฒฝ์šฐ ์ž„์‹œ ์ปฌ๋ ‰์…˜์ด ์ƒ์„ฑ๋œ๋‹ค. 

map์ด๋‹ค filter๊ฐ™์€ ์ปฌ๋ ‰์…˜ ํ•จ์ˆ˜๋ฅผ ์—ฐ์‡„ํ•˜๋ฉด ๋งค ๋‹จ๊ณ„๋งˆ๋‹ค ์ค‘๊ฐ„ ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๋ฅผ ์ƒˆ๋กœ์šด ์ž„์‹œ ์ปฌ๋ ‰์…˜์— ์ €์žฅ๋œ๋‹ค. ์ฆ‰, ๋งค ๋‹จ๊ณ„ ๋งˆ๋‹ค ๋ถˆํ•„์š”ํ•œ ์ปฌ๋ ‰์…˜์ด ์ƒ์„ฑ๋œ๋‹ค.

๐Ÿ“Œ ๋™์ž‘ ๊ณผ์ •

val resultList = people.map(Person::name).filter { it.startsWith("A") }
  1. ์œ„ ์˜ˆ์ œ์—์„œ map์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๋Š” ์ž„์‹œ ์ปฌ๋ ‰์…˜์ด ์ƒ์„ฑ๋˜๊ณ  
  2. ๊ทธ ์ž„์‹œ ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•œ filter ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ resultList๋กœ ์ €์žฅํ•œ๋‹ค.

๐Ÿ‘€ sequence๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž„์‹œ ์ปฌ๋ ‰์…˜์ด ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.

์ฝ”ํ‹€๋ฆฐ์—์„œ ์ œ๊ณตํ•˜๋Š” ์‹œํ€€์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ค‘๊ฐ„ ์ž„์‹œ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ์ปฌ๋ ‰์…˜ ์—ฐ์‚ฐ์„ ์—ฐ์‡„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ ๋™์ž‘ ๊ณผ์ •

people.asSequence().map(Person::name).filter { it.startsWith("A") }.toList()
  1. ์ค‘๊ฐ„ ์—ฐ์‚ฐ (map)์˜ ์ฒ˜๋ฆฌ๋Š” ์—ฐ๊ธฐ๋œ๋‹ค. 
  2. ์ตœ์ข… ์—ฐ์‚ฐ์„ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ์—ฐ๊ธฐ๋๋˜ ๋ชจ๋“  ๊ณ„์‚ฐ์ด ์ˆ˜ํ–‰๋œ๋‹ค. 

๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ํ•„์š”๊ฐ€ ์ƒ๊ธฐ๋ฉด(์ตœ์ข… ์—ฐ์‚ฐ ํ˜ธ์ถœ), ๊ทธ ๋•Œ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์„ ์ ์šฉํ•œ๋‹ค. 

(java์—์„œ Stream๊ฐ์ฒด์˜ ๋™์ž‘๊ณผ ๊ฐ™๋‹ค.)

๐Ÿ“Œ์‚ฌ์šฉ ๋ฐฉ๋ฒ•  

โœ… asSequence

val resultListFromSequence =
    people.asSequence().map(Person::name).filter { it.startsWith("A") }.toList()

์ปฌ๋ ‰์…˜์— ๋Œ€ํ•˜์—ฌ asSequence๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์–ด๋–ค ์ปฌ๋ ‰์…˜์ด๋“  ์‹œํ€€์Šค๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. 

โœ… generateSequence

generageSquence๋Š” ์ผ๋ฐ˜ ํ•จ์ˆ˜์ฒ˜๋Ÿผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด์ „ ์›์†Œ๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„ ๋‹ค์Œ ์›์†Œ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.

val naturalNumbers = generateSequence(0) { it + 1 }
val numbersTo100 = naturalNumbers.takeWhile { it <= 100 }
println(naturalNumbers) // kotlin.sequences.GeneratorSequence@5034c75a
println(numbersTo100) // kotlin.sequences.TakeWhileSequence@396a51ab
println(numbersTo100.sum()) // 5050

์ค‘๊ฐ„์— generateSequence๊ฐ€ ๋ฆฌํ„ดํ•œ ๊ฐ์ฒด๋ฅผ ์ถœ๋ ฅํ•ด๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, ์ปฌ๋ ‰์…˜์ด ์•„๋‹ˆ๋ผ sequence ์ž์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ฆ‰, ๊ฒฐ๊ณผ ์ค‘๊ฐ„์—๋Š” ์ปฌ๋ ‰์…˜์ด ์ƒ์„ฑ๋˜์ง€ ์•Š๊ณ , ์ตœ์ข… ์—ฐ์‚ฐ์— ํ•ด๋‹นํ•˜๋Š” sum์„ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ๊ฒฐ๊ณผ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๐Ÿ“Œ sequence์˜ ์žฅ์ 

  1. ์•ž์„œ ๋งํ–ˆ๋“ฏ์ด ์ค‘๊ฐ„ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•  ์ž„์‹œ ์ปฌ๋ ‰์…˜์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค. 
  2. ์›์†Œ์— ์—ฐ์‚ฐ์„ ์ฐจ๋ก€๋Œ€๋กœ ์ ์šฉํ•˜๋‹ค๊ฐ€ ๊ฒฐ๊ณผ๊ฐ€ ์–ป์–ด์ง€๋ฉด ๊ทธ ์ดํ›„ ์›์†Œ์— ๋Œ€ํ•ด์„œ๋Š” ์—ฐ์‚ฐ์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
println(listOf(1, 2, 3, 4, 5, 6).map { it * it }.find { it > 10 })

์œ„์™€ ๊ฐ™์€ ๊ณ„์‚ฐ์ด ์žˆ์„ ๋•Œ, ์šฐ๋ฆฌ๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒฐ๊ณผ๋Š” 4์ด๋‹ค. (find๋Š” ๋žŒ๋‹ค๋กœ ์ง€์ •ํ•œ ์—ฐ์‚ฐ์— ํ•ด๋‹นํ•˜๋Š” ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•จ)

โœ… sequence๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ

์ผ๋ฐ˜์ ์ธ ์ปฌ๋ ‰์…˜ ์—ฐ์‚ฐ ์—ฐ์‡„ ๋™์ž‘ ๊ณผ์ •

  1. ์ „์ฒด ์ปฌ๋ ‰์…˜ ์›์†Œ๋“ค์— ๋Œ€ํ•˜์—ฌ map์—ฐ์‚ฐ ์‹คํ–‰
  2. map์—ฐ์‚ฐ ๊ฒฐ๊ณผ์— ๋Œ€ํ•˜์—ฌ find์‹คํ–‰ ( > 10 ์ธ ์ฒซ ๋ฒˆ์งธ ์›์†Œ ์ฐพ๊ธฐ)

โœ… sequence๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ

sequence๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋™์ž‘ ๊ณผ์ •

  1. ๊ฐ ์›์†Œ์— ๋Œ€ํ•˜์—ฌ ์ˆœ์ฐจ์ ์œผ๋กœ map ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•œ ๋‹ค์Œ -> find ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•œ๋‹ค. 
  2. 4๋ฒˆ์งธ ์›์†Œ๊ฐ€ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋’ค ์›์†Œ 5, 6์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ฌด ์—ฐ์‚ฐ๋„ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค. 

๐Ÿค” ๊ทธ๋Ÿผ ํ•ญ์ƒ sequence๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ ์•„๋‹Œ๊ฐ€? 

์ด ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋‹ต์€ NO!

๐Ÿ“Œ ์ฝ”ํ‹€๋ฆฐ ๋žŒ๋‹ค์˜ ์ฃผ์š”ํ•œ ํŠน์ง• 

์ฝ”ํ‹€๋ฆฐ์—์„œ ๋žŒ๋‹ค๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•˜๋Š” ํŠน์ง•์ด ์žˆ๋‹ค. 

void postponeComputation(int delay, Runnable computation)

์˜ˆ๋ฅผ ๋“ค์–ด ์œ„์™€ ๊ฐ™์€ ์ž๋ฐ” ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ์„ ๋•Œ, Runnable ํƒ€์ž…์€ Runnable์„ ๊ตฌํ˜„ํ•œ ๋ฌด๋ช… ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ด๊ณ  ์ด ๋ถ€๋ถ„์— ๋žŒ๋‹ค๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. 

๋งŒ์•ฝ ์ € ๋ถ€๋ถ„์„ ๋žŒ๋‹ค๊ฐ€ ์•„๋‹Œ object๋กœ ์ „๋‹ฌํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

postponeComputation(1000, object :Runnable{
    override fun run(){
        println(42)
    }
}

์œ„์™€ ๊ฐ™์ด object๋กœ Runnable์„ ์ „๋‹ฌํ•˜๋ฉด ๋งค๋ฒˆ postponeComputation ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์€ object๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค! 

๋™์ผํ•œ ๊ตฌํ˜„์„ ๋žŒ๋‹ค๋กœ ํ•œ๋‹ค๋ฉด

postponeComputation(1000) { println(42) }

๋งค๋ฒˆ postponeComputation๋ฅผ ํ˜ธ์ถœํ•  ์ƒˆ๋กœ์šด object๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰, ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ์˜๋ฏธ์ด๋‹ค. ๋งค๋ฒˆ ์ด๋ฏธ ์ƒ์„ฑ๋œ runnable๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. (์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์œ ์ง€)

val runnable = Runnable { println(42) }
fun handleComputation() {
	postponeComputation(1000, runnable)
}

โœ… ํ•ญ์ƒ ๊ทธ๋Ÿฐ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค!

๋žŒ๋‹ค๊ฐ€ ๋žŒ๋‹ค ์™ธ๋ถ€์˜ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋งค๋ฒˆ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค. (object๋กœ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ ์ฒ˜๋Ÿผ)

์ด๋ ‡๊ฒŒ ๋žŒ๋‹ค์—์„œ ์™ธ๋ถ€ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ '๋ณ€์ˆ˜ ์บก์ณ'๋ผ๊ณ  ํ•œ๋‹ค. 

fun handleComputation(id: String) { // ๋žŒ๋‹ค ์•ˆ์—์„œ id ๋ณ€์ˆ˜ ์‚ฌ์šฉ
	postponeComputation(1000) { println(id) } // ๋žŒ๋‹ค ํ˜ธ์ถœ ์‹œ ๋งˆ๋‹ค ๋งค๋ฒˆ ์ƒˆ๋กœ์šด Runnable ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ 
}

โœ… ์ธ๋ผ์ด๋‹์„ ํ†ตํ•ด ๋ณ€์ˆ˜ ์บก์ณ์‹œ ๋ถ€๊ฐ€๋น„์šฉ ์—†์• ๊ธฐ

์•„๋ž˜ ์ฒ˜๋Ÿผ inlineํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ด๋ฉด ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , ์‹คํ–‰ํ•  ๋•Œ ๋žŒ๋‹ค๋กœ ์ „๋‹ฌํ•œ ํ•จ์ˆ˜๊ฐ€ ๋ณธ๋ฌธ์— ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผ๋œ๋‹ค. 

์ฆ‰ ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด sum์„ ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๋ถ„์—์„œ sum์„ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค. 

inline fun sum(a: Int, b: Int) = a + b
fun main() {
    val a = 1
    val b = 2
    val result = sum(a, b)
}

์ž‘์„ฑํ•œ ์ฝ”๋“œ

inline fun sum(a: Int, b: Int) = a + b
fun main() {
    val a = 1
    val b = 2
    val result = a + b
}

์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ

๐Ÿ“Œ ๊ทธ๋ž˜์„œ sequence๋ž‘์€ ๋ฌด์Šจ ์ƒ๊ด€์ธ๋ฐ?

๋Œ๊ณ  ๋Œ์•„.. ๋‹ค์‹œ sequence! 

์ฝ”ํ‹€๋ฆฐ์—์„œ ์ปฌ๋ ‰์…˜์˜ ํ•จ์ˆ˜๋Š” ์ธ๋ผ์ธ ํ•จ์ˆ˜์ด๋‹ค. ์ธ๋ผ์ธ ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ์ถ”๊ฐ€ ๊ฐ์ฒด๋‚˜ ํด๋ž˜์Šค ์ƒ์„ฑ์€ ์—†๋‹ค.

์ปฌ๋ ‰์…˜ ์ผ๋ฐ˜ ํ˜ธ์ถœ  ์‹œํ€€์Šค
์ปฌ๋ ‰์…˜์˜ ์ค‘๊ฐ„ ๊ฒฐ๊ณผ ๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ์ž„์‹œ ์ปฌ๋ ‰์…˜์„ ๋งŒ๋“ ๋‹ค.  ์ค‘๊ฐ„ ์ž„์‹œ ์ปฌ๋ ‰์…˜์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. 
๋žŒ๋‹ค๊ฐ€ ์ธ๋ผ์ด๋‹ ๋œ๋‹ค. → ํ˜ธ์ถœ ์‹œ ์ถ”๊ฐ€ ๊ฐ์ฒด๋‚˜ ํด๋ž˜์Šค ์ƒ์„ฑ์€ ์—†๋‹ค  ๋žŒ๋‹ค๊ฐ€ ์ธ๋ผ์ด๋‹ ๋˜์ง€ ์•Š๋Š”๋‹ค → ํ˜ธ์ถœ ์‹œ ๋ณ„๋„ ๊ฐ์ฒด ์ƒ์„ฑ 

๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์‹œํ€€์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ค‘๊ฐ„ ์ž„์‹œ ์ปฌ๋ ‰์…˜์€ ๋งŒ๋“ค์ง€ ์•Š์ง€๋งŒ, ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๋ณ„๋„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๋Š” ์†Œ๋ฆฌ๋‹ค.

๐Ÿ‘€ ๊ทธ๋Ÿผ sequence๋Š” ์–ธ์ œ ์“ธ๊นŒ?

์œ„์™€ ๊ฐ™์€ ์ด์œ ๋กœ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ์ปฌ๋ ‰์…˜ ์—ฐ์‚ฐ์— asSequence๋ฅผ ๋ถ™์—ฌ์„œ๋Š” ์•ˆ๋œ๋‹ค.

์‹œํ€€์Šค ์—ฐ์‚ฐ์—์„œ๋Š” ๋žŒ๋‹ค๊ฐ€ ์ธ๋ผ์ด๋‹๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํฌ๊ธฐ๊ฐ€ ์ž‘์€ ์ปฌ๋ ‰์…˜์€ ์˜คํžˆ๋ ค ์ผ๋ฐ˜ ์ปฌ๋ ‰์…˜ ์—ฐ์‚ฐ์ด ๋” ์„ฑ๋Šฅ์ด ๋‚˜์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์‹œํ€€์Šค๋ฅผ ํ†ตํ•ด ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋Š” ์ปฌ๋ ‰์…˜ ํฌ๊ธฐ๊ฐ€ ํฐ ๊ฒฝ์šฐ ๋ฟ์ด๋‹ค. 

 

์ถœ์ฒ˜ : Kotlin in action

๋ฐ˜์‘ํ˜•