0Pricing
Kotlin Academy · Урок

Операторы Flow: map, filter, transform и take

Применяйте промежуточные операторы для преобразования и ограничения выдачи Flow.

«Операторы Flow: map, filter, transform и take» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Что такое поток

Flow — это холодный асинхронный поток. Промежуточные операторы, такие как map, filter и transform, выполняются лениво — только при сборе потока.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun numbers(): Flow<Int> = flow {
    repeat(5) { emit(it + 1) }
}
fun main() = runBlocking {
    numbers().collect { println(it) }
}

Оператор преобразования

map преобразует каждое выданное значение. Это преобразование один к одному, применяемое лениво.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..5).asFlow()
        .map { it * it }
        .collect { println(it) } // 1 4 9 16 25
}

Оператор фильтрации

filter пропускает только элементы, соответствующие условию, отбрасывая остальные.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..10).asFlow()
        .filter { it % 2 == 0 }
        .collect { println(it) } // 2 4 6 8 10
}

Оператор трансформации

transform — самый универсальный оператор: для каждого входного элемента можно выдать ноль, одно или несколько значений.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..3).asFlow()
        .transform { n ->
            emit("Item $n")
            emit("Done $n")
        }
        .collect { println(it) }
}

Оператор ограничения количества

take(n) получает только первые n элементов, а затем отменяет исходный поток.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    flow {
        repeat(100) { emit(it) }
    }.take(3)
     .collect { println(it) } // 0 1 2
}

Отбор и пропуск по условию

takeWhile получает элементы, пока условие истинно, а dropWhile пропускает элементы, пока условие не станет ложным.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..10).asFlow()
        .takeWhile { it < 5 }
        .collect { println(it) } // 1 2 3 4

    (1..10).asFlow()
        .dropWhile { it < 5 }
        .collect { println(it) } // 5 6 7 8 9 10
}

Объединение операторов в цепочку

Операторы можно компоновать: каждый оператор возвращает новый Flow, что позволяет создавать декларативные конвейеры.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..20).asFlow()
        .filter { it % 3 == 0 }
        .map { it * 2 }
        .take(4)
        .collect { println(it) } // 6 12 18 24
}

Преобразование с отбрасыванием нулевых значений

mapNotNull за один шаг преобразует значения и отбрасывает результаты null — это эквивалентно конструкции map + filter { it != null }.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    flowOf("1", "two", "3", "four", "5")
        .mapNotNull { it.toIntOrNull() }
        .collect { println(it) } // 1 3 5
}

Последовательное объединение потоков

flatMapConcat преобразует каждый элемент в поток и последовательно объединяет результаты.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..3).asFlow()
        .flatMapConcat { n -> flowOf("$n-a", "$n-b") }
        .collect { println(it) }
}

Побочные эффекты для каждого элемента

onEach выполняет побочное действие для каждого элемента, не изменяя поток, — это удобно для ведения журнала или аналитики в конвейере.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..5).asFlow()
        .onEach { println("Processing: $it") }
        .filter { it % 2 == 0 }
        .collect { println("Collected: $it") }
}

Поток является холодным

Каждый вызов collect запускает поток заново. Ни один элемент не выдаётся и не преобразуется, пока терминальный оператор не инициирует сбор.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = (1..3).asFlow().map { println("map $it"); it * 2 }
    println("Before collect")
    flow.collect { println("got $it") }
    println("Second collect:")
    flow.collect { println("got $it") }  // runs again
}

Быстрая проверка

Какой оператор выдаёт ноль, одно или несколько значений для каждого элемента исходного потока?

Итоги

Преобразование выполняется один к одному; фильтрация отбрасывает элементы; трансформация выдаёт любое количество значений; ограничение ограничивает их число. Объединяйте операторы в декларативную цепочку — поток является холодным и выполняется только при сборе.

Часто задаваемые вопросы

Урок «Операторы Flow: map, filter, transform и take» бесплатный?

Да — полный текст урока «Операторы Flow: map, filter, transform и take» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «Операторы Flow: map, filter, transform и take»?

Применяйте промежуточные операторы для преобразования и ограничения выдачи Flow. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Операторы Flow: map, filter, transform и take»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Операторы Flow: map, filter, transform и take
  2. catch и onCompletion: обработка ошибок в Flow
  3. combine и zip: объединение нескольких Flow
  4. flowOn и buffer: контекст и противодавление
← Назад к Kotlin Academy