0Pricing
Kotlin Academy · レッスン

パイプラインのチェーンとSequenceによる中間リストの回避

複数ステップのパイプラインを構築し、Sequenceで遅延評価を行います。

「パイプラインのチェーンとSequenceによる中間リストの回避」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。

問題: 中間リスト

各コレクション操作(filter、map など)は新しいリストを作成します。大規模なコレクションや長い連結処理では、メモリと時間が無駄になります。

先行評価と遅延評価

コレクション操作は先行評価です。各ステップで次の処理に進む前にリスト全体を処理します。Sequence 操作は遅延評価です。次の要素に進む前に、1 つの要素をすべてのステップに通します。

Sequence への変換

asSequence() を呼び出すと、先行評価(リスト)から遅延評価(シーケンス)による処理に切り替えられます。
val result = (1..1_000_000)
    .asSequence()
    .filter { it % 2 == 0 }
    .map { it * it }
    .take(5)
    .toList()
println(result)  // [4, 16, 36, 64, 100]

Sequence は遅延評価: 終端操作まで処理しない

終端演算子(toList、first、sum など)を呼び出すまで、計算は行われません。
val seq = generateSequence(1) { it + 1 }  // infinite!
    .filter { it % 3 == 0 }
    .map { it * it }
val first5 = seq.take(5).toList()
println(first5)  // [9, 36, 81, 144, 225]

generateSequence: 無限シーケンス

generateSequence は遅延評価される無限シーケンスを作成します。
val fibonacci = generateSequence(Pair(0, 1)) { (a, b) -> Pair(b, a + b) }
    .map { it.first }
val first10 = fibonacci.take(10).toList()
println(first10)  // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

sequence ビルダー

yield を使う sequence { } ビルダーで、カスタムの遅延シーケンスを作成できます。
val evens = sequence {
    var n = 0
    while (true) {
        yield(n)
        n += 2
    }
}
println(evens.take(5).toList())  // [0, 2, 4, 6, 8]

Sequence を使う場面

次の条件に当てはまる場合に Sequence を使用してください。コレクションが大きい(>1000 要素)、複数の操作を連結している、または結果の一部だけが必要である。

Sequence を使わない場面

小規模なコレクション(<100 要素)では、シーケンスによるオーバーヘッドが発生します。短い連結処理では、イテレーターを基盤とする仕組みのほうが遅くなります。
// Overkill for small list:
listOf(1, 2, 3).asSequence().map { it * 2 }.toList()
// Just use:
listOf(1, 2, 3).map { it * 2 }

Sequence の終端操作

終端操作によって処理が開始されます。よく使うものは、toList()、first()、last()、count()、sum()、any()、all()、none() です。
val s = (1..100).asSequence().filter { it % 7 == 0 }
println(s.first())          // 7
println(s.count())          // 14
println(s.sum())            // 728

状態を持つ操作と持たない操作

一部の Sequence 操作(sort、distinct など)は状態を持ちます。出力を生成する前にすべての要素を確認する必要があるため、遅延評価が中断されます。
val s = (1..10).asSequence()
    .filter { it > 3 }   // stateless: lazy
    .sorted()            // stateful: must see all elements
    .take(3).toList()
println(s)  // [4, 5, 6]

constrainOnce: 1 回の反復を保証

constrainOnce() を使用すると、シーケンスが複数回反復されたときに例外をスローするようにできます。ストリームに便利です。
val seq = generateSequence(1) { if (it < 5) it + 1 else null }
    .constrainOnce()
val first = seq.toList()   // OK
// val second = seq.toList()  // IllegalStateException!

クイックチェック

Sequence はいつ要素の処理を開始しますか?

まとめ

Sequence は遅延評価されるため、終端操作を行うまで処理されません。大規模なコレクションで複数の操作を連結する場合は、asSequence() を使用してください。generateSequence と sequence { } は、遅延評価される無限ストリームを作成します。終端操作によって処理が開始されます。

よくある質問

「パイプラインのチェーンとSequenceによる中間リストの回避」レッスンは無料ですか?

はい。「パイプラインのチェーンとSequenceによる中間リストの回避」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。

「パイプラインのチェーンとSequenceによる中間リストの回避」で何を学びますか?

複数ステップのパイプラインを構築し、Sequenceで遅延評価を行います。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Kotlin Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「パイプラインのチェーンとSequenceによる中間リストの回避」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このKotlin Academyレッスンでコードを書いて実行できますか?

はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. mapとflatMap:すべての要素を変換する
  2. filter、filterNot、partition
  3. fold、reduce、runningFold
  4. パイプラインのチェーンとSequenceによる中間リストの回避
← Kotlin Academyに戻る