Malakai
Malakai

Reputation: 3131

Generate unique string within specific length range

I faced some difficulties to figure out how to generate unique string within [1;200) range length. The code I've come up with attached below:

public static String generateRandString() {

    String STRING_TOKENS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
    StringBuilder stringBuilder = new StringBuilder();
    Random random = new Random();
    while(stringBuilder.length() <= 200) {
        int index = (int) random.nextFloat() * STRING_TOKENS.length();
        stringBuilder.append(STRING_TOKENS.charAt(index));
    }

    return stringBuilder.toString();
}

The Problem:

Requesting 20 generated strings returns every time "AAAAAAAA" string probably of 200 symbols length

Expected output:

A7898as7sd6as5da
as87asd67
768asjhg435GhA900324
2g2j3h4gjhgAKL*78a9dd879234
3B234
1

Some limitations:

  1. No additional libraries (Google Guava or Apache Common)
  2. JDK 1.6 only

Many thanks to your contribution!

Upvotes: 3

Views: 4124

Answers (5)

rossum
rossum

Reputation: 15685

Others have talked about making random strings. For guaranteed uniqueness you could use the string's hash code. If two strings have different hash codes then they are guaranteed not to be the same. As each string is generated, put its hash code into a set/array/whatever. If the hash code is already there (unlikely but possible) then reject that particular string and generate an alternative.

I'm not sure what is available in Java 1.6, so I won't write any actual code, but the idea is not difficult to implement.

Upvotes: 1

Mike Adamenko
Mike Adamenko

Reputation: 3002

Use int index = random.nextInt(STRING_TOKENS.length());

In Java 1.7 or later, the standard way to to generate a random int value, but in a specific range is as follows:

import java.util.concurrent.ThreadLocalRandom;

// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);

See javadoc

Before Java 1.7

 int randomNum = random.nextInt((max - min) + 1) + min;

Upvotes: 2

tobias_k
tobias_k

Reputation: 82899

This line:

int index = (int) random.nextFloat() * STRING_TOKENS.length();

Here, you cast random.nextFloat() to int before the multiplication, thus always ending up with 0 * something. Add some parentheses:

int index = (int) (random.nextFloat() * STRING_TOKENS.length());

Or better, use nextInt instead:

int index = random.nextInt(STRING_TOKENS.length());

If you also want to randomize the length of the string, roll another number for use in the condition in the while loop:

int max = random.nextInt(200);
while(stringBuilder.length() <= max) {

Upvotes: 2

Naghaveer R
Naghaveer R

Reputation: 2944

Try this !!!

for (int i = 0; i < 10; i++)
        System.out.println(randomString(ThreadLocalRandom.current().nextInt(0, 200)));


static String randomString(int len) {
    String AB = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    Random rnd = new Random();
    StringBuilder sb = new StringBuilder(len);
    for (int i = 0; i < len; i++)
        sb.append(AB.charAt(rnd.nextInt(AB.length())));
    return sb.toString();
}

If you want to generate unique string. You can use java.util.UUID

import java.util.UUID;
String uuid = UUID.randomUUID().toString();

Upvotes: 4

user6073886
user6073886

Reputation:

In your line (int) random.nextFloat() * STRING_TOKENS.length() your int cast will be applied only to random.nextFloat() and since this value is between 0.0 and 1.0 the result of that cast will almost allways be 0 and your whole value will be 0 as well (As 0 * X is 0).

Use parenthesis: (int) (random.nextFloat() * STRING_TOKENS.length()) to apply the cast to the whole expression.

Upvotes: 2

Related Questions