简体   繁体   中英

How to return a random value within a range, from a Map with Integer and List of Longs in Java

I am trying to find a way to get a random value from a provided list of different ranges using ThreadLocalRandom , and return that one random value from a method. I've been trying different approaches, and not having much luck.

I've tried this:

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

But I could not figure out how to get a random value out of it for a specific range, so thought I'd try the Map approach, I tried creating a Map of Integers and List of Longs:

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

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

I am not sure how to store those value ranges into the Map.

I've tried adding in values, for example:

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

I am not sure how to add the 333L to the List, I have searched and tried various things but always get errors, such as: found 'long', required List

I want the Integer in the Map to be an id for the associated range, for example, 1 for 233L-333L, so that I can tell it first, get a random Int key from the Map, for example 1, and then use ThreadLocalRandom.current().nextLong(origin, bound) where origin would be 233L and bound would be 333L, and then return a random value within that range of 233L-333L.

I am not sure if this is possible, or I am simply approaching this the wrong way - any guidance/help is appreciated!

int range = ThreadLocalRandom.current().nextInt(3);
long randomValue = ThreadLocalRandom.current().nextLong(values[range][0],values[range][1]);

this will work with the array solution you tried first. first you select the range then you get the random value.

It's pretty straightforward. Your long[][] will do fine.

First, select a random index, then select a long between values[index][0] and 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);

Of course, you could also abstract it away into some convenient classes.

Note that, for the distribution of values to be even, all ranges must have the same size (which seem to be the case in your code).

Implementation with even distribution

However, if you want to support different ranges while the distribution has to remain even, another approach is required.

We could calculate a single random number with as upper bound the total number of possible values. Then we could check in which 'bucket' the value is to be retrieved.

Here is a working example . In order to test the distribution which is said to be even, a random number is generated a million times. As you can see, each value occurs approximately 200,000 times.


1 In my examples, the upper bound is exclusive . This is consistent with many methods from the Java standard libraries, like ThreadLocalRandom.nextLong(origin, bound) or LongStream.range(long start, long end) .

The easiest is the most straight forward.

   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);
   }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM