It’s not clear what getRandomChar() does that it is worth building another Stream operation around it. It’s much simpler to stream over random values in the first place.
E.g., the following code generates random strings consisting of upper case letters in the A-Z range:
public static String nextString() {
return ThreadLocalRandom.current().ints(stringLength, 'A', 'Z'+1)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
If the intended characters do not form a consecutive range, you can use a string constant naming the allowed characters, e.g.
public static String nextString() {
String allowed = "XO+";
return ThreadLocalRandom.current().ints(stringLength, 0, allowed.length())
.map(allowed::charAt)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
Granted, this collector doesn’t hide the StringBuilder the same way, Collectors.joining() does, but on the other hand, this operation has no boxing overhead and doesn’t create temporary strings.
You can use a similar operation to built the character pool String:
static final String ASCII_LETTERS_AND_NUMBERS =
IntStream.concat(IntStream.concat(
IntStream.rangeClosed('A', 'Z'), IntStream.rangeClosed('a', 'z')),
IntStream.rangeClosed('0', '9'))
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
public static String nextString() {
return ThreadLocalRandom.current()
.ints(stringLength, 0, ASCII_LETTERS_AND_NUMBERS.length())
.map(ASCII_LETTERS_AND_NUMBERS::charAt)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
or, to challenge the reader of the random string:
static final String ALL_LETTERS_AND_NUMBERS =
IntStream.rangeClosed(32, Character.MAX_VALUE)
.filter(Character::isLetterOrDigit)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
public static String nextString() {
return ThreadLocalRandom.current()
.ints(stringLength, 0, ALL_LETTERS_AND_NUMBERS.length())
.map(ALL_LETTERS_AND_NUMBERS::charAt)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
return IntStream.range(0, strLenght).map(i -> getRandomChar()).collect(Collectors.joining(""));got compilation problems, I tried that before, because of this error I published my question