← Назад к вопросам

Что такое Lambda функция?

1.0 Junior🔥 201 комментариев
#Kotlin основы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Lambda функция в Kotlin/Java

Lambda функция (или лямбда) — это анонимная функция, которую можно передавать как значение, хранить в переменной, или использовать как параметр в другую функцию. Это мощный инструмент функционального программирования.

Основной синтаксис

// Синтаксис лямбды:
// { параметры -> тело функции }

// Простая лямбда
val add = { a: Int, b: Int -> a + b }
val result = add(5, 3)  // 8

// Без параметров
val greeting = { "Hello, World!" }
println(greeting())  // Hello, World!

// С одним параметром (параметр может быть it)
val square = { x: Int -> x * x }
println(square(5))  // 25

// Или с it (неявное имя для одного параметра)
val squareWithIt = { x: Int -> x * x }
listOf(1, 2, 3).map { it * it }  // [1, 4, 9]

Лямбды как параметры функций

// Функция которая принимает лямбду
fun executeAction(action: () -> Unit) {
    println("Before")
    action()  // Вызываем лямбду
    println("After")
}

// Передаем лямбду
executeAction({ println("Executing") })

// Если лямбда последний параметр, скобки можно опустить
executeAction {
    println("Executing")
}

// Функция которая принимает лямбду с параметром
fun processNumber(number: Int, processor: (Int) -> String) {
    val result = processor(number)
    println(result)
}

// Использование
processNumber(42) { n -> "Number is $n" }
processNumber(42) { "Number is $it" }

Примеры в Android

1. Обработчик кликов

fun setupButton() {
    // До (без лямбды)
    button.setOnClickListener(object : View.OnClickListener {
        override fun onClick(v: View?) {
            navigateToDetail()
        }
    })
    
    // Сейчас (с лямбдой)
    button.setOnClickListener { navigateToDetail() }
    
    // Параметр есть но его можно игнорировать
    button.setOnClickListener { _ -> navigateToDetail() }
    
    // Или использовать как it
    button.setOnClickListener {
        Toast.makeText(context, "Clicked", Toast.LENGTH_SHORT).show()
    }
}

2. Работа со списками

val numbers = listOf(1, 2, 3, 4, 5)

// map — преобразовать каждый элемент
val doubled = numbers.map { it * 2 }  // [2, 4, 6, 8, 10]

// filter — оставить только нужные элементы
val evenNumbers = numbers.filter { it % 2 == 0 }  // [2, 4]

// forEach — выполнить действие для каждого
numbers.forEach { println(it) }

// find — найти первый элемент
val firstEven = numbers.find { it % 2 == 0 }  // 2

// groupBy — группировать по условию
val grouped = numbers.groupBy { if (it % 2 == 0) "even" else "odd" }
// {odd=[1, 3, 5], even=[2, 4]}

3. Асинхронное программирование

// Coroutines с лямбдами
viewModelScope.launch {
    val users = withContext(Dispatchers.IO) {
        userRepository.getUsers()  // Это лямбда!
    }
    
    _users.value = users
}

// Flow с лямбдами
userRepository.getUsers()
    .map { it.name }  // Лямбда
    .filter { it.length > 5 }  // Лямбда
    .collect { name ->
        // Лямбда
        println(name)
    }

4. Обработка результатов

val result: Result<User> = fetchUser()

when (result) {
    is Result.Success -> {
        val user = result.data
        println(user.name)
    }
    is Result.Error -> {
        println(result.exception.message)
    }
}

// Или с лямбдами
result.fold(
    onSuccess = { user -> println(user.name) },  // Лямбда
    onFailure = { error -> println(error.message) }  // Лямбда
)

Типы лямбд

// Лямбда без параметров и возврата
val action: () -> Unit = { println("Action") }

// Лямбда с параметром
val square: (Int) -> Int = { x -> x * x }

// Лямбда с несколькими параметрами
val add: (Int, Int) -> Int = { a, b -> a + b }

// Лямбда возвращает значение
val greeting: () -> String = { "Hello" }

// Nullable лямбда
var callback: ((String) -> Unit)? = null
callback?.invoke("message")

Продвинутые техники

1. Higher-order функции

// Функция которая возвращает лямбду
fun createMultiplier(factor: Int): (Int) -> Int {
    return { number -> number * factor }  // Лямбда как результат
}

val double = createMultiplier(2)
println(double(5))  // 10

val triple = createMultiplier(3)
println(triple(5))  // 15

2. Extension функции с лямбдами

// Extension функция apply
val user = User("", "")
user.apply {
    name = "John"
    email = "john@example.com"
}

// Extension функция let
val name: String? = getUserName()
name?.let { println(it.uppercase()) }  // Выполнится только если не null

// Extension функция also
val list = mutableListOf<String>()
list.also { println("List created with size: ${it.size}") }
  .add("item")
  .also { println("Item added") }

3. Функции которые модифицируют лямбды

// takeIf — если условие true, вернет значение
val age = 25
val canVote = age.takeIf { it >= 18 }  // 25

// takeUnless — если условие false, вернет значение
val tooYoung = age.takeUnless { it >= 18 }  // null

// also — выполнить действие и вернуть значение
val result = expensiveComputation()
    .also { println("Result: $it") }
    .also { saveToCache(it) }

4. Функции высшего порядка

// Функция которая принимает другую функцию как параметр
fun <T> applyTwice(value: T, transform: (T) -> T): T {
    return transform(transform(value))
}

val result = applyTwice(5) { it * 2 }  // 20 (5*2 = 10, 10*2 = 20)

// Функция composition
fun <T> compose(
    f: (T) -> T,
    g: (T) -> T
): (T) -> T {
    return { x -> f(g(x)) }  // Лямбда как результат
}

val addOne = { x: Int -> x + 1 }
val double = { x: Int -> x * 2 }
val composed = compose(double, addOne)  // (x+1)*2
println(composed(5))  // 12

Важные свойства лямбд

1. Замыкание (Closure)

fun createAdder(x: Int): (Int) -> Int {
    // Лямбда "помнит" переменную x
    return { y -> x + y }
}

val addFive = createAdder(5)
println(addFive(3))  // 8
println(addFive(10))  // 15

// Практичный пример
var counter = 0
val incrementCounter = {
    counter++  // Лямбда может изменять переменные из внешней области
}

incrementCounter()  // counter = 1
incrementCounter()  // counter = 2
println(counter)  // 2

2. Последовательность вызовов (Method chaining)

listOf("apple", "banana", "cherry")
    .filter { it.length > 5 }  // Лямбда 1
    .map { it.uppercase() }     // Лямбда 2
    .forEach { println(it) }    // Лямбда 3

// BANANA
// CHERRY

Лямбды vs Anonymous Classes

// Раньше (Java style, до лямбд)
button.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?) {
        navigateToDetail()
    }
})

// Сейчас (лямбда)
button.setOnClickListener { navigateToDetail() }

// Раньше (обработка списка)
val numbers = listOf(1, 2, 3)
val result = numbers.map(object : Function1<Int, Int> {
    override fun invoke(it: Int): Int = it * 2
})

// Сейчас (лямбда)
val result = numbers.map { it * 2 }

Практические примеры в проектах

// 1. ViewModel с лямбдами
class UserViewModel : ViewModel() {
    fun loadUsers(onSuccess: (List<User>) -> Unit, onError: (String) -> Unit) {
        viewModelScope.launch {
            try {
                val users = userRepository.getUsers()
                onSuccess(users)  // Вызов лямбды
            } catch (e: Exception) {
                onError(e.message ?: "Unknown error")
            }
        }
    }
}

// Использование
viewModel.loadUsers(
    onSuccess = { users -> updateUI(users) },
    onError = { error -> showError(error) }
)

// 2. Repository с лямбдами
class UserRepository(val database: UserDatabase) {
    fun getUsersForView() = database.userDao()
        .getUsers()
        .map { entities ->
            entities.map { entity ->  // Лямбда
                User(
                    id = entity.id,
                    name = entity.name,
                    email = entity.email
                )
            }
        }
        .catch { error ->
            println(error)  // Лямбда
        }
}

Итог

Lambda функция это:

  • Анонимная функция которую можно передавать
  • Значение первого класса как переменная
  • Основа функционального программирования
  • Синтаксический сахар для коротких функций

Преимущества:

  • Код компактнее и читабельнее
  • Нет нужды создавать отдельные функции
  • Отлично для callback и event handling
  • Делает код более функциональным

Когда использовать:

  • Для callback обработчиков (onClick, onSuccess)
  • При работе со списками (map, filter, forEach)
  • В асинхронном коде (coroutines, Flow)
  • Для функций высшего порядка

Лямбды — это одна из самых мощных и часто используемых возможностей современного Kotlin.