Как вернуть случайное значение в пределах диапазона, из карты с целым числом и списком длинных в Java - PullRequest
0 голосов
/ 18 июня 2019

Я пытаюсь найти способ получить случайное значение из предоставленного списка различных диапазонов, используя ThreadLocalRandom, и вернуть это одно случайное значение из метода.Я пробовал разные подходы, и мне не повезло.

Я пробовал это:

private static final Long[][] values = {
    { 233L, 333L },
    { 377L, 477L },
    { 610L, 710L }
};
// This isn't correct
long randomValue = ThreadLocalRandom.current().nextLong(values[0][0]);

Но я не мог понять, как извлечь из него случайное значение для определенного диапазона, поэтому подумал, что я попробую Map Подход, я пытался создать карту целых чисел и список длин:

private static Map<Integer, List<Long>> mapValues = new HashMap<>();

{{233L, 333L}, {377L, 477L}, {610L, 710L}} // ranges I want

Я не уверен, как сохранить эти диапазоны значений в карте.

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

// Need to get the other value for the range in here, in this case 333L
map.put(1, 233L);

Я не уверен, как добавить 333L в список, я искал и пробовал разные вещи, но всегда получаю ошибки, такие как: найдено 'long', обязательный список

Я хочу, чтобы целое число в карте было идентификатором для соответствующего диапазона, например, 1 для 233L-333L, чтобы я мог сначала сказать это, получить случайный ключ Int из карты, например 1, а затем используйте ThreadLocalRandom.current().nextLong(origin, bound), где источник будет 233L, а предел будет 333L, а затем вернет случайное значение в пределах этого диапазона 233L-333L.

Я не уверен, возможно ли это, или япросто неправильный подход - любое руководство / помощь приветствуются!

Ответы [ 3 ]

1 голос
/ 18 июня 2019

Это довольно просто.Ваш long[][] будет в порядке.

Сначала выберите случайный индекс, затем выберите длинное значение от values[index][0] до values[index][1] 1 .

long[][] values = {
    { 233L, 333L },
    { 377L, 477L },
    { 610L, 710L }
};

// Select a random index
int index = ThreadLocalRandom.current().nextInt(0, values.length);

// Determine lower and upper bounds
long min = values[index][0];
long max = values[index][1];
long rnd = ThreadLocalRandom.current().nextLong(min, max);

Конечно, вы также можете абстрагировать его в несколько удобных классов.

Обратите внимание, что для равномерного распределения значений все диапазоны должны иметь одинаковый размер (который, по-видимому,в вашем коде).

Реализация с равномерным распределением

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

Мы могли бы вычислить одно случайное число с верхней границей общего числа возможных значений.Затем мы можем проверить, в каком «контейнере» должно быть получено значение.

Вот рабочий пример .Чтобы проверить распределение, которое называется четным, случайное число генерируется миллион раз.Как видите, каждое значение встречается примерно 200 000 раз.


1 В моих примерах верхняя граница равна exclusive .Это согласуется со многими методами из стандартных библиотек Java, такими как ThreadLocalRandom.nextLong(origin, bound) или LongStream.range(long start, long end).

1 голос
/ 18 июня 2019
int range = ThreadLocalRandom.current().nextInt(3);
long randomValue = ThreadLocalRandom.current().nextLong(values[range][0],values[range][1]);

это будет работать с решением для массива, которое вы пробовали первым. сначала вы выбираете диапазон, затем вы получаете случайное значение.

0 голосов
/ 18 июня 2019

Самый простой - самый прямой.

   private static final long[][] values = { { 233L, 333L
         }, { 377L, 477L
         }, { 610L, 710L
         }
   };

   public static void main(String[] args) {
      for (long v[] : values) {
         long low = v[0];
         long high = v[1];
         System.out.println("Between " + low + " and " + high + " -> "
               + getRandom(low, high));
      }
   }

   public static long getRandom(long low, long high) {
      // add 1 to high to make range inclusive
      return ThreadLocalRandom.current().nextLong(low, high + 1);
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...