144

I am looking for solution to pick number randomly from an integer array.

For example I have an array new int[]{1,2,3}, how can I pick a number randomly?

thecoshman
  • 8,394
  • 8
  • 55
  • 77
BreakHead
  • 10,480
  • 36
  • 112
  • 165

13 Answers13

243
public static int getRandom(int[] array) {
    int rnd = new Random().nextInt(array.length);
    return array[rnd];
}
Chris Dennett
  • 22,412
  • 8
  • 58
  • 84
  • 3
    yes, but you've to tell that `generator` is an instance of `java.util.Random` – stivlo Nov 09 '11 at 13:17
  • 35
    I wouldn't create `Random()` each time you run the function: the random generator is supposed to have history. If it haven't, it's extremely predictable. It's not a problem at all in this case — but it should be mentioned that `array[(int)(System.currentTimeMillis() % array.length)]` is just as good as the proposed solution. – alf Nov 09 '11 at 13:42
  • 8
    @alf, that is far far from as good as the proposed solution. `new Random()` tries to create an instance that has a different seed than any previously created `Random`. Your approach would break horribly just by invoking the function twice in short time. – aioobe Nov 09 '11 at 13:55
  • 1
    @alf some systems don't have a to-the-millisecond accurate clock which may preclude some options if `gcd(array.length,clockAccuracy)!=1` – ratchet freak Nov 09 '11 at 14:00
  • Well, it does have `++seedUniquifier` inside, and uses `nanoTime()` instead of `currentTimeMillis()` — but it's still perfectly predictable. – alf Nov 09 '11 at 14:02
  • 1
    Note: I did new Random() precisely because of the seed issue I've experienced in the past, although you can just use setSeed(..) and use an incremented var w/ nanotime. – Chris Dennett Nov 09 '11 at 14:14
  • 3
    I just noticed a notification that I downvoted this answer - I must have clicked it accidentally; unfortunately the interface won't let me undo it (it says I can't change my vote unless the answer is edited...). So, apologies to Chris Dennett. – Peter Hanley Apr 19 '16 at 22:29
  • I wouldn't apologise, new object creation is crap. It's ridiculous that you can't create a new random in a `Random` easily – Chris Dennett May 16 '17 at 11:09
  • I would make this answer of yours similar to [this](https://stackoverflow.com/a/363692/5515060), e.g. don't show how you can create a `Random` instance, because `new Random()` is potentially pretty bad – Lino Sep 21 '20 at 08:39
  • `ThreadLocalRandom` has an unknown seed, so if you find the seed you can replace the numbers coming out of `tlr.next()`. You can't get a new `ThreadLocalRandom` with a random seed unless you're in a different thread, and even then the randomness may be linked in a predictable way dependent on how/when the threads were created. Creating a new `Random` each time invokes the contract of a "random" seed for each instance. – Chris Dennett Sep 24 '20 at 16:32
  • 1
    A forewarning: you might get an IllegalArgumentException if your array has a size of zero because rand.nextint(n) returns an integer from 0 (inclusive) to 0 (exclusive). See https://stackoverflow.com/a/19304656/8917573. – thegoodhunter-9115 Nov 22 '20 at 01:35
  • Technically the IllegalArgumentException type is valid (although the exception contents may not be relevant) – Chris Dennett Nov 26 '20 at 16:08
18

You can use the Random generator to generate a random index and return the element at that index:

//initialization
Random generator = new Random();
int randomIndex = generator.nextInt(myArray.length);
return myArray[randomIndex];
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
15

If you are going to be getting a random element multiple times, you want to make sure your random number generator is initialized only once.

import java.util.Random;

public class RandArray {
    private int[] items = new int[]{1,2,3};

    private Random rand = new Random();

    public int getRandArrayElement(){
        return items[rand.nextInt(items.length)];
    }
}

If you are picking random array elements that need to be unpredictable, you should use java.security.SecureRandom rather than Random. That ensures that if somebody knows the last few picks, they won't have an advantage in guessing the next one.

If you are looking to pick a random number from an Object array using generics, you could define a method for doing so (Source Avinash R in Random element from string array):

import java.util.Random;

public class RandArray {
    private static Random rand = new Random();

    private static <T> T randomFrom(T... items) { 
         return items[rand.nextInt(items.length)]; 
    }
}
Community
  • 1
  • 1
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
9

With Java 7, one can use ThreadLocalRandom.

A random number generator isolated to the current thread. Like the global Random generator used by the Math class, a ThreadLocalRandom is initialized with an internally generated seed that may not otherwise be modified. When applicable, use of ThreadLocalRandom rather than shared Random objects in concurrent programs will typically encounter much less overhead and contention. Use of ThreadLocalRandom is particularly appropriate when multiple tasks (for example, each a ForkJoinTask) use random numbers in parallel in thread pools.

public static int getRandomElement(int[] arr){
    return arr[ThreadLocalRandom.current().nextInt(arr.length)];
}

//Example Usage:
int[] nums = {1, 2, 3, 4};
int randNum = getRandomElement(nums);
System.out.println(randNum);

A generic version can also be written, but it will not work for primitive arrays.

public static <T> T getRandomElement(T[] arr){
   return arr[ThreadLocalRandom.current().nextInt(arr.length)];
}

//Example Usage:
String[] strs = {"aa", "bb", "cc"};
String randStr = getRandomElement(strs);
System.out.println(randStr);
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
5

Use the Random class:

int getRandomNumber(int[] arr)
{
  return arr[(new Random()).nextInt(arr.length)];
}
moongoal
  • 2,847
  • 22
  • 23
4

You can also use

public static int getRandom(int[] array) {
    int rnd = (int)(Math.random()*array.length);
    return array[rnd];
}

Math.random() returns an double between 0.0 (inclusive) to 1.0 (exclusive)

Multiplying this with array.length gives you a double between 0.0 (inclusive) and array.length (exclusive)

Casting to int will round down giving you and integer between 0 (inclusive) and array.length-1 (inclusive)

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
  • Math.random() return a double and not an int. If it would have there would have been just two possible values 0 and 1. – Akshay R. Feb 27 '18 at 12:03
3

use java.util.Random to generate a random number between 0 and array length: random_number, and then use the random number to get the integer: array[random_number]

James.Xu
  • 8,249
  • 5
  • 25
  • 36
2

Java has a Random class in the java.util package. Using it you can do the following:

Random rnd = new Random();
int randomNumberFromArray = array[rnd.nextInt(3)];

Hope this helps!

decden
  • 679
  • 4
  • 19
1

Since you have java 8, another solution is to use Stream API.

new Random().ints(1, 500).limit(500).forEach(p -> System.out.println(list[p]));

Where 1 is the lowest int generated (inclusive) and 500 is the highest (exclusive). limit means that your stream will have a length of 500.

 int[] list = new int[] {1,2,3,4,5,6};
 new Random().ints(0, list.length).limit(10).forEach(p -> System.out.println(list[p])); 

Random is from java.util package.

Johnny Willer
  • 3,717
  • 3
  • 27
  • 51
1

Take a look at this question:

How do I generate random integers within a specific range in Java?

You will want to generate a random number from 0 to your integers length - 1. Then simply get your int from your array:

myArray[myRandomNumber];
Community
  • 1
  • 1
Brian DiCasa
  • 9,369
  • 18
  • 65
  • 97
-1
package workouts;

import java.util.Random;

/**
 *
 * @author Muthu
 */
public class RandomGenerator {
    public static void main(String[] args) {
     for(int i=0;i<5;i++){
         rndFunc();
     } 
    }
     public static void rndFunc(){
           int[]a= new int[]{1,2,3};
           Random rnd= new Random();
           System.out.println(a[rnd.nextInt(a.length)]);
       }
}
-1

You can also try this approach..

public static <E> E[] pickRandom_(int n,E ...item) {
        List<E> copy = Arrays.asList(item);
        Collections.shuffle(copy);
        if (copy.size() > n) {
            return (E[]) copy.subList(0, n).toArray();
        } else {
            return (E[]) copy.toArray();
        }

    }
Ravi Sapariya
  • 395
  • 2
  • 11
  • So you shuffle a list with `O(nlogn)` time complexity, make the copy of it twice using the total of 3 times as much memory as the initial array, even though the problem that OP asked about can be solved with `O(1)` time complexity and `O(1)` memory...? – Jaroslaw Pawlak May 04 '18 at 11:07
  • yes, you are right, It was better to do with constant time and space complexity. – Ravi Sapariya May 04 '18 at 11:49
-1
package io.github.baijifeilong.tmp;

import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream;

/**
 * Created by BaiJiFeiLong@gmail.com at 2019/1/3 下午7:34
 */
public class Bar {
    public static void main(String[] args) {
        Stream.generate(() -> null).limit(10).forEach($ -> {
            System.out.println(new String[]{"hello", "world"}[ThreadLocalRandom.current().nextInt(2)]);
        });
    }
}
BaiJiFeiLong
  • 3,716
  • 1
  • 30
  • 28