Avatar ·

Как получить случайное число в Kotlin? (Int, Double, Long, Float)

Всем привет! Я только начал изучать Kotlin и перешел с Java. В Java я привык использовать `Math.random()` или `Random` класс, но в Kotlin я вижу, что синтаксис немного другой. Мне нужно решить простую задачу: написать игру "Угадай число". Компьютер загадывает число от 1 до 100, а пользователь пытается его угадать. Я попробовал написать такой код: ```kotlin fun main() { val secretNumber = Math.random() * 100 + 1 println("Угадай число: $secretNumber") } ``` Но это выдаёт число с кучей знаков после запятой, например: `42.718293847`. Мне же нужно целое число. Я посмотрел в сторону класса `java.util.Random`, но он кажется мне слишком громоздким для такой простой задачи. В документации я видел упоминания про `kotlin.random.Random`, но не совсем понял, как его правильно использовать. Подскажите, пожалуйста, как в Kotlin (для JVM) получить: 1. Случайное целое число в заданном диапазоне (например, от 1 до 100). 2. Случайное число с плавающей точкой (Double) от 0.0 до 1.0. 3. Случайный элемент из списка. Буду благодарен за примеры кода и объяснение, какой способ считается "правильным" и идиоматичным для Kotlin. Заранее спасибо! <<>>

Лучший способ: используйте встроенный kotlin.random.Random

В Kotlin есть собственный, идиоматичный способ работы со случайными числами — это функция kotlin.random.Random. Вам не нужно импортировать java.util.Random или использовать Math.random(), хотя технически они тоже работают. Kotlin предлагает более чистый и лаконичный API.

1. Случайное целое число (Int) в диапазоне

Для получения целого числа от 1 до 100 включительно используйте метод nextInt() с указанием диапазона:

import kotlin.random.Random

fun main() {
    // Диапазон [1, 100], где 1 — start, 101 — until (граница не включена)
    val secretNumber = Random.nextInt(1, 101)

    println("Загаданное число: $secretNumber")
    // Вывод: Загаданное число: 42 (каждый раз разное)
}

Важно: Метод nextInt(from, until) генерирует число от from (включительно) до until (исключительно). Поэтому, чтобы получить диапазон от 1 до 100 включительно, нужно указать until = 101.

Есть также упрощенная версия: Random.nextInt(100) — вернет число от 0 до 99.

2. Случайное число с плавающей точкой (Double)

Для генерации случайного Double от 0.0 до 1.0 (исключительно) используйте nextDouble():

import kotlin.random.Random

fun main() {
    val randomDouble = Random.nextDouble() // от 0.0 до 1.0
    println("Случайное Double: $randomDouble")
    // Вывод: Случайное Double: 0.738291

    // Если нужно Double в другом диапазоне, например, от 0.0 до 10.0:
    val scaledDouble = Random.nextDouble(10.0) // от 0.0 до 10.0
    println("Scaled Double: $scaledDouble")
    // Вывод: Scaled Double: 4.567

    // Или от 5.0 до 10.0:
    val rangedDouble = Random.nextDouble(5.0, 10.0) // от 5.0 до 10.0
    println("Ranged Double: $rangedDouble")
}

3. Случайный элемент из списка

Для выбора случайного элемента из коллекции (список, массив) Kotlin предлагает расширение .random():

fun main() {
    val fruits = listOf("Яблоко", "Банан", "Апельсин", "Киви", "Манго")

    // Выбираем случайный фрукт
    val randomFruit = fruits.random()
    println("Сегодня я съем: $randomFruit")
    // Вывод: Сегодня я съем: Киви

    // Для пустого списка вызов .random() вызовет исключение
    // Чтобы избежать этого, используйте randomOrNull():
    val emptyList = emptyList<String>()
    val nullableFruit = emptyList.randomOrNull()
    println(nullableFruit) // Вывод: null
}

4. Воспроизводимые последовательности (Seed)

Если вам нужно, чтобы последовательность случайных чисел повторялась (например, для тестов), используйте Random(seed: Long):

import kotlin.random.Random

fun main() {
    val seededRandom = Random(12345L)

    println(seededRandom.nextInt(100)) // Всегда выведет 64 (при seed = 12345)
    println(seededRandom.nextInt(100)) // Всегда выведет 35
}

Итог: что использовать?

  • Для простых задач: используйте Random.nextInt(range), Random.nextDouble() и list.random(). Это самый простой и читаемый способ.
  • Для многопоточности: kotlin.random.Random потокобезопасен (thread-safe).
  • Не используйте Math.random() в Kotlin — это Java-стиль, который не дает преимуществ и менее гибок.

Исправленный код для вашей игры:

import kotlin.random.Random

fun main() {
    val secretNumber = Random.nextInt(1, 101) // Целое от 1 до 100
    println("Компьютер загадал число от 1 до 100. Попробуйте угадать!")
    // ... логика ввода с клавиатуры и сравнения
}
<<>>

Альтернативный подход: Использование java.util.Random (для совместимости)

Если вы пишете код, который должен быть совместим со старыми версиями Kotlin (до 1.2) или вы просто привыкли к Java-стилю, вы можете использовать классический java.util.Random. Kotlin поддерживает его "из коробки".

import java.util.Random

fun main() {
    val random = Random()

    // Целое число от 1 до 100
    val intNumber = random.nextInt(100) + 1 // nextInt(100) дает 0..99, +1 смещает
    println("Int: $intNumber")

    // Double от 0.0 до 1.0
    val doubleNumber = random.nextDouble()
    println("Double: $doubleNumber")

    // Случайный элемент списка (через индекс)
    val fruits = listOf("Яблоко", "Банан", "Апельсин")
    val randomFruit = fruits[random.nextInt(fruits.size)]
    println("Фрукт: $randomFruit")
}

Недостатки этого подхода:

  • Менее лаконично: нужно создавать экземпляр Random().
  • Нет удобных расширений, как list.random().
  • Для получения числа в диапазоне [1, 100] приходится вручную добавлять +1, что может привести к ошибке "off-by-one".

Когда это может пригодиться: Если вы используете Kotlin в Android-проекте и вам нужно передать экземпляр Random в какую-то Java-библиотеку, которая ожидает именно java.util.Random. В остальных случаях лучше использовать kotlin.random.Random — он современнее и удобнее.