Комментарии (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.