【ITニュース解説】FLOW API IN KOTLIN

2025年09月08日に「Medium」が公開したITニュース「FLOW API IN KOTLIN」について初心者にもわかりやすいように丁寧に解説しています。

作成日: 更新日:

ITニュース概要

KotlinのFlow APIは、非同期データストリームを扱うためのもの。コルーチンと連携し、データの生成、変換、消費を効率的に行う。従来のシーケンスに比べ、非同期処理に強く、バックプレッシャーにも対応。リアルタイムデータ処理やUIの更新などに適している。

出典: FLOW API IN KOTLIN | Medium公開日:

ITニュース解説

KotlinのFlow APIは、非同期データストリームを扱うための強力なツールだ。従来のコレクション(リストやセットなど)が一度に全てのデータを保持するのに対し、Flowは必要に応じてデータを生成し、処理する。これは、大量のデータを扱う場合や、ネットワーク経由でデータをストリーミングする場合に特に有効だ。

Flowの基本的な概念は、データの発行(emit)と収集(collect)だ。Flowは、エミッタ(Emitter)と呼ばれる特別な関数を使ってデータを生成し、コレクタ(Collector)と呼ばれる別の関数を使ってそれらのデータを受け取る。この発行と収集の間に、様々な操作(オペレータ)を適用してデータを変換、フィルタリング、集約することができる。

Flowはコルーチンと密接に連携しており、非同期処理を簡単に記述できる。コルーチンは、中断可能(suspendable)な処理を記述するための軽量なスレッドのようなものだ。Flowは、コルーチンの中で実行され、非同期的にデータを生成し、処理する。

Flowの作成は、flow { ... } ブロックを使用して行う。このブロックの中で emit() 関数を呼び出すことで、データをFlowに発行できる。例えば、1から5までの整数を生成するFlowは、以下のように記述できる。

1import kotlinx.coroutines.flow.*
2import kotlinx.coroutines.*
3
4fun main() = runBlocking {
5    flow {
6        for (i in 1..5) {
7            emit(i)
8        }
9    }.collect { value ->
10        println(value)
11    }
12}

このコードは、1から5までの整数を順番に出力する。flow { ... } ブロックはFlowを生成し、collect { ... } はFlowからデータを受け取り、処理する。runBlocking は、コルーチンを実行するための関数だ。

Flowには、様々なオペレータが用意されており、データの変換やフィルタリングを簡単に行うことができる。よく使われるオペレータには、mapfiltertransform などがある。

  • map: Flowから発行される各データを別のデータに変換する。例えば、整数を文字列に変換したり、オブジェクトの特定のプロパティを抽出したりできる。
1flow {
2    emit(1)
3    emit(2)
4    emit(3)
5}.map { value ->
6    "Number: $value"
7}.collect { value ->
8    println(value) // Output: Number: 1, Number: 2, Number: 3
9}
  • filter: Flowから発行されるデータのうち、特定の条件を満たすものだけを通過させる。例えば、偶数のみをフィルタリングしたり、特定の文字列を含むデータのみを抽出したりできる。
1flow {
2    emit(1)
3    emit(2)
4    emit(3)
5    emit(4)
6    emit(5)
7}.filter { value ->
8    value % 2 == 0
9}.collect { value ->
10    println(value) // Output: 2, 4
11}
  • transform: より複雑な変換を行うための汎用的なオペレータ。mapfilter の機能を組み合わせたり、複数の値を生成したりできる。
1flow {
2    emit(1)
3    emit(2)
4    emit(3)
5}.transform { value ->
6    if (value % 2 == 0) {
7        emit("Even: $value")
8    } else {
9        emit("Odd: $value")
10    }
11}.collect { value ->
12    println(value) // Output: Odd: 1, Even: 2, Odd: 3
13}

これらのオペレータは、チェーンのように繋げて使用することもできる。これにより、複雑なデータ処理パイプラインを簡潔に記述することができる。

1flow {
2    emit(1)
3    emit(2)
4    emit(3)
5    emit(4)
6    emit(5)
7}.filter { value ->
8    value % 2 == 0
9}.map { value ->
10    "Even Number: $value"
11}.collect { value ->
12    println(value) // Output: Even Number: 2, Even Number: 4
13}

Flowは、ホットフロー(Hot Flow)とコールドフロー(Cold Flow)の2種類に分類される。コールドフローは、コレクタが存在しない場合はデータを生成しない。つまり、collect() が呼び出されたときに初めてデータの生成が開始される。一方、ホットフローは、コレクタの有無に関わらず常にデータを生成し続ける。これは、例えば、UIイベントやセンサーデータなどのリアルタイムデータを扱う場合に適している。

ホットフローの例としては、StateFlowSharedFlow がある。StateFlow は、常に最新の値を保持し、新しいコレクタが接続されたときにその値をすぐに提供する。SharedFlow は、複数のコレクタに対して値を共有し、必要に応じて値をバッファリングすることができる。

Flowは、エラーハンドリングもサポートしている。catch オペレータを使用することで、Flow内で発生した例外を捕捉し、処理することができる。これにより、エラーが発生した場合でも、Flow全体の処理を中断することなく、安全に継続することができる。

1flow {
2    emit(1)
3    emit(2)
4    throw Exception("Something went wrong")
5    emit(3) // This will not be emitted
6}.catch { e ->
7    println("Caught exception: ${e.message}")
8}.collect { value ->
9    println(value) // Output: 1, 2, Caught exception: Something went wrong
10}

Flowは、非同期データストリームを扱うための強力なツールであり、Kotlinのコルーチンと組み合わせることで、複雑な非同期処理を簡潔に記述することができる。初心者にとって最初は少し難しく感じるかもしれないが、基本的な概念とオペレータを理解することで、より効率的で保守性の高いコードを書くことができるようになるだろう。特に、バックエンドAPIとの通信や、UIにおけるデータ更新など、非同期処理が不可欠な場面でその威力を発揮する。Flowをマスターすることは、モダンなKotlinアプリケーション開発において非常に重要なスキルとなる。

関連コンテンツ

【ITニュース解説】FLOW API IN KOTLIN | いっしー@Webエンジニア