1

I am trying to have a piece of code in which a random number would be generated and will be saved in a collection so next time when another random number is generated i can check if this new number is already in list or not.

The main point of this method would be generating a number in ranged of 1 to 118, no duplicated number allowed.

Random rand = new Random();
    randomNum2 = rand.nextInt(118) + 1;
    if (!generated.contains(randomNum2))
    {
        String strTemp = "whiteElements\\"+String.valueOf(randomNum2)+".JPG";
        btnPuzzlePiece2.setIcon(new ImageIcon(strTemp));
        generated.add(randomNum2);
        btnPuzzlePiece2.repaint();
    }
    else 
        setPicForBtnGame1();

BUT the problem is in this piece of code as the program continues generating numbers the possibility to have a correct random number (in range without duplicating) imagine after running the method 110 times... the possibility for the method to generate a valid random number reduces to less than 1%... which leaves the program with the chance of never having the list of numbers from 1-118 and also too much waste of process.

so how can i write this correctly? p.s i thought of making 118 object and save them in a collection then generate a random object and after remove the object from the list so the next element has no chance of being duplicated.

Help me out please ...

  • 2
    possible duplicate of [Creating random numbers with no duplicates](http://stackoverflow.com/questions/4040001/creating-random-numbers-with-no-duplicates) – Emil Laine Feb 12 '15 at 16:49
  • Does this help: [java-generate-random-range-of-specific-numbers-without-duplication-of-those-nu][1] [1]: http://stackoverflow.com/questions/5224877/java-generate-random-range-of-specific-numbers-without-duplication-of-those-nu – Bill Ryder Feb 12 '15 at 16:55
  • nope... i tried it before i write the post.. – Behnam Ezazi Feb 12 '15 at 17:05
  • 1
    "Random...check for dups" is almost always the wrong thing to do. Especially for such a tiny set as 118 objects. Just allocate an array with the numbers 1 to 118, then properly *shuffle* it (Google "Fisher-Yates"). – Lee Daniel Crocker Feb 12 '15 at 18:04

2 Answers2

5

Create a List, and populate it with the elements in your range. Then shuffle() the list, and the order is your random numbers. That is, the 0-th element is your first random number, the 1st element is your second random number, etc.

Kon
  • 10,702
  • 6
  • 41
  • 58
  • 1
    Because you beat me to it +1. – Rudi Kershaw Feb 12 '15 at 16:51
  • 1
    I'm sorry could you be more specific... i'm kind of a newbie – Behnam Ezazi Feb 12 '15 at 16:51
  • 1
    @BehnamEzazi OK. Which part of the above is confusing? I won't write out the whole code for you but I'd be happy to explain in more detail the tricky part. – Kon Feb 12 '15 at 16:54
  • @Kon well i didn't ask for the code :D just explanation would do for me :)i'm not familiar with the Collection.shuffle() my guesses are that this method will change the order of the list randomly..., which will generates a random ordered list of 1 to 118, the difference is i have to populate my list with int 1-118 then use the shuffle() to change the order and simply use the elements.. am i correct? – Behnam Ezazi Feb 12 '15 at 16:59
  • @BehnamEzazi Yep, perfectly correct. And you're right about what `shuffle()` does, but when it doubt, always reference the Javadocs. They're well-written and easy to understand. http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#shuffle%28java.util.List%29 – Kon Feb 12 '15 at 17:16
-1

Wouldn't it be better to just generate something that can never be a duplicate? A random number with no duplicates is usually known as a UUID.

The easiest way to generate a UUID is to prefix your random number with the current system time in milliseconds. Of course there's a chance that it could be a duplicate but it's vanishingly small. Of course it might be long, so you'd want to then base64 encode it for example, to reduce it's size.

You can get a more or less guaranteed UUID down to about 8 characters using encoding.

Richard
  • 1,070
  • 9
  • 22