简体   繁体   中英

Finding and removing duplicates elements of an array

I am creating a lottery class to generate 5 unique lottery numbers (no repeats of used digits). I am having trouble locating and removing any repeats from the array. What am I missing?

public class Lottery {
    private int lotteryNumber[] = new int[5];

    public Lottery() {
        Random myRan = new Random();

        for (int i = 0; i < lotteryNumber.length; i++) {
            lotteryNumber[i] = myRan.nextInt(9) + 1;
            for (int j = i + 1; j < lotteryNumber.length; j++) {
                if ((lotteryNumber[i] == (lotteryNumber[j])) && (i != j)) {
                    System.out.println("Duplicate Element is : " + lotteryNumber[i]);
                    i--;
                }
            }
            System.out.println(lotteryNumber[i]);
        }
    }
}

It continues to print out the duplicates despite my efforts. Thank you in advance for your help

I would use a LinkedHashSet<Integer> to generate the desired number of digits (and then you can convert it to an array and preserve the original order). Something like,

final int len = 5;
Random rand = new Random();
Set<Integer> set = new LinkedHashSet<>(len);
while (set.size() < len) {
    set.add(rand.nextInt(10));
}
Integer[] arr = set.toArray(new Integer[len]);
System.out.println(Arrays.toString(arr));

or shuffle 10 digits and take the first five. Something like

Integer[] digits = new Integer[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Collections.shuffle(Arrays.asList(digits));
Integer[] lottery = Arrays.copyOf(digits, 5);
System.out.println(Arrays.toString(lottery));

You might also consider using a HashSet to accomplish this:

public class Lottery {

    private Collection<Integer> lotteryNumbers = new HashSet<>();

    public Lottery() {

        Random rand = new Random();
        while (lotteryNumbers.size() < 5) {
            this.lotteryNumbers.add(rand.nextInt(9) + 1); 
        }
    }

    public Collection getNumbers() {
        return this.lotteryNumbers;
    }

    public Integer[] getNumbersAsArray() {
        return this.lotteryNumbers.toArray();
    }
}

Try this only a small modification to your code...

import java.util.*;
import java.io.*;
public class Lottery {
    private int lotteryNumber[] = new int[5];
    public Lottery() {
        Random myRan = new Random();
        for (int i = 0; i < lotteryNumber.length; i++)
        {
            lotteryNumber[i] = myRan.nextInt(9)+1;
            for (int j = 0; j < i; j++)
            {
                if( (lotteryNumber[i] == (lotteryNumber[j])) && (i != j) )
                {
                    i=0;
                }
            }
        }
        System.out.println("final values are");
        for(int i = 0; i < lotteryNumber.length; i++){
            System.out.println(lotteryNumber[i]);
        }
    }
}

Use a Set to store already seen numbers, like so:

final Random rnd = new Random(System.currentTimeMillis());
final Set<Integer> seenNumbers = new HashSet<>();

int index = 0;
int number;

while (index < 5) {
    number = rnd.nextInt(9) + 1;
    if (seenNumbers.add(number))
        lotteryNumbers[index++] = number;
}

Even with this, you have the problem that this may take a very long time; your initial set size is 10 and you pick 5 out of this set, randomly. You will eventually get a result, of course, but this may take a long time to get there. I don't know the maths behind it, though.

You can get the use of a LinkedHashSet in this case :
(Hence the LinkedHashSet doesn't keep duplicate values )

public static <T> T[] removeDuplicates(T[] arr) {
    return (T[]) new LinkedHashSet<T>(Arrays.asList(arr)).toArray();
}

Then you can remove duplicates:

removeDuplicates(new Integer[] { 3,6,7,7,3 })

Out-put :

// [3,6,7]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM