0

i want to create an array of 10000 unique random elements. Till now i only figure out how to create random integers and fill an array and finding the doubles and deleted them. But this decrease the size of the array which i dont want it. So the question is how i can fill an array with unique integers as elements without decreasing the size of the array.

Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69
gdk 10
  • 17
  • 5

4 Answers4

2

You could use this code. Usage of Set will eliminate duplicates and you are fetching random numbers until you get 10000 different random integers.

Set<Integer> numbers = new HashSet<>();
Random r = new Random();
while (numbers.size() < 10000) {
    numbers.add(r.nextInt(100000));
}
Integer[] a = new Integer[numbers.size()];
a = numbers.toArray(a);
Ivan
  • 8,508
  • 2
  • 19
  • 30
  • The common homework assignment, asked many times here on Do My Homework For Me Stackoverflow, requires the use of only arrays, no Collection classes. Which, of course, puts artificial limits on answers, but that's what homework is like. – Stephen P Jan 17 '18 at 00:36
  • Yes it generates the unique numbers but i want it in random order.Should i use collections.Shuffle? – gdk 10 Jan 17 '18 at 00:57
  • I was about to suggest shuffle as an alternative method. If the number range required is the same or close to the size of the list, it may become exponentially slower finding random numbers which aren't already present. An alternative method is to shuffle a list of numbers 0 to n, and then possible truncate the list if required. – slipperyseal Jan 17 '18 at 01:00
  • @gdk10 the numbers in set are in random order. These are several first numbers in one of executions: 65537, 49152, 16385, 2, 16388, 32773, 49158 – Ivan Jan 17 '18 at 01:03
  • @gdk10 the hashset above doesnt preserve insert order. iterating the values will return them in an order determined by the internal hash buckets. - which might seem random but will have some kind of pattern to it. LinkedHashSet retains insertion order You could use that one. But im not sure how memory hungry it is. – slipperyseal Jan 17 '18 at 01:03
0

Try this logic:

USE AN ARRAYLIST ENTIRELY, THEN CONVERT TO AN ARRAY AT THE END OF THE ENTIRE OPERATION.

Declare an arraylist

For every random number generated, check if the number already exists in the arraylist (using the .contains() method). If it does, repeat the process, else, move to the next number.

Code example:

    Arraylist<Integer> arr = new Arraylist<>();

    arr.add(generate());  //I included this line so that the arraylist won't be empty

    //Note that the method *generate()* generates a new random number

    for(int i = 0; i < 9999; i++){

        int next = generate();  //the method that generates your number

        if(arr.contains(next)){
            i--;   //The entire operation will be repeated for this index.
        }
        else{
            arr.add(next);   //Add the number to the arraylist
        }
    }

    int[] finalArray = arr.toArray();    //Your final resultant array!

I hope this helps.. Merry coding!

Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69
0

I found this great solution:

This solution doesn't need any Collection class.

public static int[] createRandomNumbers(int howMany) {
    int n = howMany + 1;

    int a[] = new int[n];

    for (int i = 0; i < n; i++) {
        a[i] = i;
    }

    int [] result = new int[n];

    int  x = n;
    SecureRandom rd = new SecureRandom();

    for (int i = 0; i < n; i++) {
        int k = rd.nextInt(x);

        result[i] = a[k];

        a[k] = a[x-1];

        x--;
    }

    return result;
}

System.out.println(Arrays.toString(createRandomNumbers(10000)));

Reference: Best way to create a list of unique random numbers in Java

Hope it helps

Ele
  • 33,468
  • 7
  • 37
  • 75
0

You can use Set. This Collection that contains no duplicate elements.

Documentation https://docs.oracle.com/javase/7/docs/api/java/util/Set.html

Set<Integer> numbers = new HashSet();

do {
    numbers.add(ThreadLocalRandom.current().nextInt());
} while(numbers.size() < 10000);