Класс Lazy

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

Импорт

kotlinimport kotlin.Lazy

Синтаксис

kotlinval lazyValue: Lazy<T> = lazy(initializer: () -> T)
kotlinval lazyValue: Lazy<T> = lazy(mode: LazyThreadSafetyMode, initializer: () -> T)

Пример

Создадим ленивое значение, которое вычисляется только при первом обращении:

kotlinval lazyValue: Lazy<String> = lazy {
  println("Computed only once!")
  "Hello, Kotlin!"
}

println(lazyValue.value)
println(lazyValue.value)

Результат выполнения кода:

kotlinComputed only once!
String "Hello, Kotlin!"
String "Hello, Kotlin!"

Пример

Использование различных режимов потокобезопасности:

kotlinval lazySync: Lazy<Int> = lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
  println("Synchronized computation")
  42
}

val lazyPub: Lazy<Int> = lazy(LazyThreadSafetyMode.PUBLICATION) {
  println("Publication computation")
  100
}

val lazyNone: Lazy<Int> = lazy(LazyThreadSafetyMode.NONE) {
  println("None computation")
  200
}

println(lazySync.value)
println(lazyPub.value)
println(lazyNone.value)

Результат выполнения кода:

kotlinSynchronized computation
Int 42
Publication computation
Int 100
None computation
Int 200

Пример

Проверка, было ли значение уже вычислено:

kotlinval lazyData: Lazy<List<Int>> = lazy {
  println("Computing large list...")
  listOf(1, 2, 3, 4, 5)
}

println("Is initialized: " + lazyData.isInitialized())
println(lazyData.value)
println("Is initialized: " + lazyData.isInitialized())

Результат выполнения кода:

kotlinBoolean false
Computing large list...
List<Int> [1, 2, 3, 4, 5]
Boolean true

Пример

Ленивая инициализация сложного объекта:

kotlinclass ExpensiveResource {
  init {
    println("Expensive resource created")
  }
  
  fun use() {
    println("Using resource")
  }
}

val resource: Lazy<ExpensiveResource> = lazy { ExpensiveResource() }

println("Before first access")
resource.value.use()
resource.value.use()

Результат выполнения кода:

kotlinString "Before first access"
String "Expensive resource created"
String "Using resource"
String "Using resource"

Смотрите также

  • класс Any,
    корневой тип иерархии классов Kotlin
  • класс Observable,
    для реализации наблюдаемых свойств
  • класс Vetoable,
    для свойств с возможностью вето изменений
  • интерфейс Sequence,
    для ленивых последовательностей элементов