edi233
edi233

Reputation: 3031

Arrays and random value

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?

Upvotes: 0

Views: 236

Answers (6)

arne.b
arne.b

Reputation: 4340

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).

Upvotes: 2

Zhivko Draganov
Zhivko Draganov

Reputation: 1253

        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)

Upvotes: 0

AlexR
AlexR

Reputation: 115388

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. 

Upvotes: 1

Mark Byers
Mark Byers

Reputation: 839074

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.

Upvotes: 1

user unknown
user unknown

Reputation: 36269

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);

Upvotes: 3

paxdiablo
paxdiablo

Reputation: 882466

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.

Upvotes: 3

Related Questions