2016年2月12日

Kotlin 遅延評価型と先行評価型のコレクション操作関数

"ことりん" の名前が気に入ったので色々調査中・・・
(・8・) × >ω</

Kotlin のコレクション操作関数(C# の LINQ to Object、Java の Stream API 相当)は、1.0.0-rc-1036 時点で stdlib に 2 種類用意されている。
Sequence インターフェース の拡張関数(遅延評価型)と、Iterable インターフェース の拡張関数(先行評価型)である。
※ スカラ値を返す関数(any, count, max 等)は両方とも先行評価型

よって、正確には、LINQ to Object や Stream API 相当になるのは、Sequence 拡張関数の方になる。

[Sequence と Iterable 拡張関数の比較]

fun main(args: Array<String>) {
    val source = 0..3
    lazyEvaluationMethods(source)
    println()
    eagerEvaluationMethods(source)
}

// 数字リストから偶数のみを抽出して 2 倍する

fun lazyEvaluationMethods(source : Iterable<Int>) {
    var result = source.asSequence().filter {
        println("sequence.filter : $it")
        it % 2 == 0
    }.map {
        println("sequence.map : $it")
        it * 2
    }.toList()
    println(result)
}

fun eagerEvaluationMethods(source : Iterable<Int>) {
    var result = source.filter {
        println("iterable.filter : $it")
        it % 2 == 0
    }.map {
        println("iterable.map : $it")
        it * 2
    }
    println(result)
}
[結果]
sequence.filter : 0
sequence.map : 0
sequence.filter : 1
sequence.filter : 2
sequence.map : 2
sequence.filter : 3
[0, 4]

iterable.filter : 0
iterable.filter : 1
iterable.filter : 2
iterable.filter : 3
iterable.map : 0
iterable.map : 2
[0, 4]

検証環境

  • jdk 1.8.0_74
  • Kotlin 1.0.0-rc-1036

雑記

Sequence と Iterable の違いを知ってないと割と危険な実装をしてしまいそう・・・
Iterable 拡張関数の方は戻り値が kotlin.collections.List 型なのですぐに気付くはず。
その List の実装は、今のところ java.util.ArrayList が利用されている。

0 件のコメント:

コメントを投稿