0

I am trying to generate unique random number using the below function. Whenerver I run my code in a loop of 1000, it generates duplicate number also.

Code

private static String randomize() {
        int count = 10;
        List<Integer> digits = createList(count);
        Collections.shuffle(digits); // this re-arranges the elements in the list
        return listToString(digits);
    }

    private static <T> String listToString(List<T> list) {
        StringBuilder result = new StringBuilder();
        for (T object : list) {
            result.append(object);
        }
        return result.toString();
    }

    private static List<Integer> createList(int size) {
        List<Integer> result = new ArrayList<Integer>(size);
        for (int i = 0; i < size; i++) {
            result.add(i);
        }
        return result;
    }

public static void main(String[] args) {
        for (int i = 0; i < 1000; i++) {
            String strName = randomize();
            System.out.println(strName);
        }

I searched a lot in google and tried ThreadLocal also, it did not help me. Any help or guide on this will be really helpful. My idea is to generate 10 digit non-repeating random number within a loop.

user4324324
  • 559
  • 3
  • 7
  • 25

1 Answers1

1

You're not really generating random numbers, are you? You're generating random permutations of the 10 unique digits [0..9]. (e.g. "0123456789", "9834105672", etc.) Since there are only 3268800 (10!) unique permutations, you have a decent chance of hitting a duplicate with 1000 tries.

(I haven't worked out the math, but since 1000^2 is within an order of magnitude of 10!, my intuition tells me there's at least a 10% chance of a duplicate in any given set. Google "birthday paradox" for details.)

What you want to do, and what @Andrei is trying to explain, is to check/store the result every time you call randomize() to make sure you don't have duplicates. Roughly:

public static void main(String[] args) {
    Set<String> results = new HashSet<>(1000);
    while (results.size() < 1000) {
        String strName = randomize();
        if (!results.contains(strName)) {
            System.out.println(strName);
            results.add(strName);
        }
    }
}

Unless of course you actually want a set of random numbers:

public static void main(String[] args) {
    Set<Long> results = new HashSet<>(1000);
    while (results.size() < 1000) {
        // Random number on [1E9..1E10]
        long random = (long) (Random.nextDouble() * 900000000L) + 100000000L;
        if (!results.contains(random)) {
            System.out.println(random);
            results.add(random);
        }
    }
}
DavidW
  • 1,413
  • 10
  • 17