Avatar ·

Как генерировать случайные числа в заданном диапазоне в Android на Kotlin?

Всем привет! Я новичок в разработке под Android и пишу приложение на Kotlin. Мне нужно генерировать случайное число в определённом диапазоне, например, от 1 до 10 (включительно) или от 5 до 50. Я пробовал использовать `Random().nextInt()`, но он возвращает случайное число от 0 до максимального значения, а мне нужно именно в моём диапазоне. Вот что я писал: ```kotlin val randomNumber = Random().nextInt(10) // даёт число от 0 до 9 ``` Я хочу, чтобы число было, скажем, от 1 до 10 или от 10 до 20. Пробовал прибавлять смещение, но иногда выходит за границы. Подскажите, как правильно это сделать на Kotlin? Желательно, чтобы код был совместим с Android API 21+ (это минимальная версия в моём проекте). Заранее спасибо! Также интересует, есть ли разница между `java.util.Random` и `kotlin.random.Random`? Какой из них лучше использовать в Android-проектах? <<>>

Генерация случайных чисел в диапазоне на Kotlin

В Kotlin есть несколько элегантных способов решить эту задачу. Начнём с самого простого и рекомендуемого подхода — использования стандартной функции из стандартной библиотеки Kotlin.

1. Использование kotlin.random.Random (рекомендуемый способ)

Начиная с Kotlin 1.3, в стандартной библиотеке есть свой класс kotlin.random.Random. Он предоставляет удобные функции-расширения для генерации чисел в диапазоне:

import kotlin.random.Random

// Случайное число от 1 до 10 включительно
val number1 = Random.nextInt(1, 11)  // 11 — это верхняя граница (не включается)

// Случайное число от 5 до 50 включительно
val number2 = Random.nextInt(5, 51)

// Случайное число от 0 до 99
val number3 = Random.nextInt(100)    // эквивалентно Random.nextInt(0, 100)

Важно: Второй параметр (верхняя граница) не включается в результат. Поэтому, чтобы получить диапазон [1, 10], нужно передать 11.

2. Использование java.util.Random (классический способ)

Если вам нужно работать с Java-совместимым кодом или вы используете старую версию Kotlin, то можно использовать стандартный Java-класс:

import java.util.Random

val random = Random()
// Число от 1 до 10
val number1 = random.nextInt(10) + 1  // 0..9 + 1 = 1..10

// Число от 5 до 50
val number2 = random.nextInt(46) + 5  // 0..45 + 5 = 5..50

// Универсальная формула: min + random.nextInt(max - min + 1)

3. Лучшая практика для Android

Для Android-приложений рекомендуется:

  • Использовать kotlin.random.Random — он кроссплатформенный, потокобезопасный (по умолчанию) и написан на Kotlin.
  • Не создавать новый экземпляр Random каждый раз — это может привести к повторяющимся числам при быстрой генерации. Лучше использовать общий экземпляр:
// Плохо:
fun getRandomNumber(): Int = Random.nextInt(1, 11)

// Хорошо:
val random = Random
fun getRandomNumber(): Int = random.nextInt(1, 11)

4. Генерация чисел с плавающей точкой

// Double от 0.0 до 1.0
val double1 = Random.nextDouble()

// Double от 5.0 до 10.0
val double2 = Random.nextDouble(5.0, 10.0)

// Float от 0.0 до 1.0
val float1 = Random.nextFloat()

5. Безопасность (криптостойкость)

Если случайные числа используются для безопасности (пароли, токены), используйте java.security.SecureRandom:

import java.security.SecureRandom

val secureRandom = SecureRandom()
val secureNumber = secureRandom.nextInt(100) // 0..99

6. Совместимость с API 21+

Все приведённые примеры работают на Android API 21+ без каких-либо дополнительных настроек. kotlin.random.Random доступен с Kotlin 1.3, который поддерживается на всех современных версиях Android.

Итог

Для большинства задач используйте kotlin.random.Random.nextInt(min, max) — это самый чистый и идиоматичный способ на Kotlin. Не забывайте, что верхняя граница не включается в результат.

<<>>

Альтернативный подход: использование Extension-функций

Если вы часто генерируете случайные числа, можно создать собственные функции-расширения для класса Int или Random:

import kotlin.random.Random

// Расширение для Int
fun Int.Companion.randomBetween(min: Int, max: Int): Int {
    return Random.nextInt(min, max + 1)
}

// Использование
val randomAge = Int.randomBetween(18, 65)

// Расширение для Random
fun Random.nextIntInRange(min: Int, max: Int): Int {
    return this.nextInt(min, max + 1)
}

val myRandom = Random
val diceRoll = myRandom.nextIntInRange(1, 6)

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

Дополнительный совет: Если вы используете java.util.Random и хотите избежать повторяющихся последовательностей при быстрых вызовах (например, в цикле), создайте один экземпляр Random на уровне класса или используйте ThreadLocalRandom из Java:

import java.util.concurrent.ThreadLocalRandom

val number = ThreadLocalRandom.current().nextInt(1, 11) // 1..10

Но в Kotlin это обычно не требуется, так как kotlin.random.Random уже оптимизирован для таких случаев.