1

I am trying to generate n random numbers between 0-31 in my Android code. Below is the code that I am using:

int max_range = 31;
SecureRandom secureRandom = new SecureRandom();
int[] digestCodeIndicesArr = new int[indices_length];
int i = 0, random_temp = 0;

while (i != indices_length-1) {
    random_temp = secureRandom.nextInt(max_range);
    if (!Arrays.asList(digestCodeIndicesArr).contains(random_temp)) {
        digestCodeIndicesArr[i] = random_temp;
        i++;
    }
}

indices_length is the number of random numbers that I need. It's generally 6,7 or 9. But when I print the generated array, I generally end up seeing duplicates. Can someone point out the mistake I am making. I have added the below line of code to filter out random duplicates:

if (!Arrays.asList(digestCodeIndicesArr).contains(random_temp))

Thanks in advance!

Sid
  • 1,224
  • 3
  • 23
  • 48
  • what exacly do you want to do? that the 9 nubers will be different? 'cause your code is ok for what you wrote in English. Random behaves like that: sometimes you throw the same number one after the other even with a dice. – Gavriel Jan 27 '16 at 18:31
  • Or duplicate of [Creating random numbers with no duplicates](http://stackoverflow.com/q/4040001/5221149), which has more description, and alternative for large valueset. – Andreas Jan 27 '16 at 18:32
  • 1
    @Tunaki, we don't even know yet what does he want to achieve, how can you say it's a duplicate? – Gavriel Jan 27 '16 at 18:32
  • 1
    @Gavriel We do know, because OP said that "seeing duplicates" was a "mistake". – Andreas Jan 27 '16 at 18:33
  • Or the mistake is that he doesn't understand that it happens once in a while – Gavriel Jan 27 '16 at 18:37
  • I do understand that getting duplicates is a possibility. For the same reason I added this line of code: if (!Arrays.asList(digestCodeIndicesArr).contains(random_temp)). so that if the array already contains the number being generated now, we will skip it – Sid Jan 27 '16 at 19:09
  • @Gavriel: The problem is not that the random number getting generated is a duplicate. I am confused as to how digestCodeIndicesArr is getting populated with a duplicate when I have the below condition: if (!Arrays.asList(digestCodeIndicesArr).contains(random_temp)). Shouldn't this condition filter out any duplicate random number being generated. – Sid Jan 27 '16 at 19:15
  • 1
    @Andreas: I am not saying that seeing duplicates is a mistake. I am confused as to how my array is getting populated with duplicates even when I have put a check for the same. – Sid Jan 27 '16 at 19:17
  • Thanks Sid. @Tunaki, I rest my case. This is not a duplicate IMHO – Gavriel Jan 27 '16 at 19:21
  • @Tunaki: I have edited my question. Hope that it makes you understand the problem that I am facing. – Sid Jan 27 '16 at 19:22
  • 1
    Fair enough, reopened. – Tunaki Jan 27 '16 at 19:22
  • 1
    Although the duplicate link that was provided by @Tunaki didn't tell you what you did wrong, it did actually tell you how to do it right. As explained in [my answer](http://stackoverflow.com/a/35046336/5221149), your use of `Arrays.asList` was wrong. – Andreas Jan 27 '16 at 19:38

2 Answers2

1

Arrays.asList(digestCodeIndicesArr) does not produce a List<Integer> with size() == digestCodeIndicesArr.length.
It produces a List<int[]> with size() == 1, where first (and only) element is the array.
As such, it will never contain random_temp, so ! contains() is always true.

It is bad for performance to constantly create a list and perform a sequential search to check for duplicates. Use a Set instead, that you maintain in parallel with the array, or use a LinkedHashSet first, then convert to array.

Anyway, this explains why your code wasn't working. The duplicate link that Tunaki had provided and the duplicate link I provided in comment, explains how to actually do what you were trying to do.

Community
  • 1
  • 1
Andreas
  • 154,647
  • 11
  • 152
  • 247
1

You need to change:

int[] digestCodeIndicesArr = new int[indices_length];

to:

Integer[] digestCodeIndicesArr = new Integer[indices_length];

because Arrays.asList(digestCodeIndicesArr) is List<int[]>, and not what you thought probably (List<int> or List<Integer> I guess).

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Gavriel
  • 18,880
  • 12
  • 68
  • 105