0

I have a problem with random and arrays. I have a list empty list and I want to add 8 some random values, but I don't want to some values was the same. To get some random value I use this code:

        for (int i = 0; i < 8; i++) {
            round = random.nextInt(31);
            while (temp.get(round).equals(mix)) {
                round = random.nextInt(31);
            }
            mix.add(temp.get(round));
        }

temp is list with 32 objects and mix is my list where I want to add 8 random values. But when I random some values sometimes I get the same values. How I can get random values but without duplicates?

edi233
  • 3,511
  • 13
  • 56
  • 97
  • You could convert your array to a list and use the contains method of the arraylist to check if it present. If not, add it. Else, generate a new one and try again. The conversion to list can be done by Arrays.asList() (if you're using Java 6) – Chetter Hummin Mar 21 '12 at 08:52
  • possible duplicate of [Unique random numbers in O(1)?](http://stackoverflow.com/questions/196017/unique-random-numbers-in-o1) – paxdiablo Mar 21 '12 at 09:58

6 Answers6

3

You can use a shuffle list which basically maintains a list of all possible values and removes one when it's returned to you. This is often known as the Fisher-Yates shuffle.

The removal of returned items from the list prevents the same number from being returned twice, and you can see further details, and a Java implementation, here.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
3

Make a Collection of 32 objects, shuffle them, and take the first 8 of them.

List <Integer> list = new ArrayList <Integer> ();       
for (int i = 0; i < 32; ++i)
{
    list.add (i);
}
Collections.shuffle (list);
user unknown
  • 35,537
  • 11
  • 75
  • 121
2

While others have described ways to implement a new solution, I think yours can be fixed by changing a single line:

while (temp.get(round).equals(mix))

I guess the condition is supposed to check whether the element of temp at position round is already in mix. This should do:

while (mix.contains(temp.get(round))

The problem with the first line is that equals is defined to compare an object to any other kind of object, and thus compares an element of temp, which is probably not a collection itself, to mix, which is. Thus, the condition is always false. Collection.contains is the method to use, and you need to use the one of mix. (As others have also pointed out, a Set is best suited to a case where contains is applied often, but for 8 cases, as you need, it does not matter much whether mix is a List instead).

[edit]: By the way: since the upper bound in random.nextInt(int) is excluded, you should only ever get the final element of 32-size temp in your mix if you use nextInt(32).

arne.b
  • 4,212
  • 2
  • 25
  • 44
1

You can add your numbers to a Set. Keep adding items until your set has the correct number of items.

while (set.size() < n)
{
    int item = random.nextInt(m);
    set.add(item);
}

Note that this will probably perform fine for most situations. It will however perform badly if both n is large and m - n is small.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
1

Use Set. Put your rundom values to set until its size is equal to your predefined number (e.g. 8):

Random random = new Random(System.currentTimeMillis());
Set<Integer> randomSet = new HashSet<Integer>();
while(randomSet.size() < 8) {
    randomSet.add(random.nextInt(31));
}
// now random set contains 8 different random numbers. 
AlexR
  • 114,158
  • 16
  • 130
  • 208
0
        int randomCounter = 31;

        for (int i = 0; i < 8; i++) {
        round = random.nextInt(randomCounter);
        int roundInTemp = temp.get(round);
        mix.add(rountInTemp);
        temp.remove(roundInTemp);
        randomCounter--;
    }

Other way is to shuffle temp list(with algorith you find fine) and use list.sublist(0, 8)

Zhivko Draganov
  • 1,213
  • 2
  • 10
  • 16