我正在尝试创建一个返回随机字符串字符的函数,但我正在尝试使用lambdas,我的函数看起来像:
public static String nextString() {
return IntStream.range(0, 10).map(i -> getRandomChar()).XXX
}
private static Character getRandomChar() {
//returns a random Character object
}
我不知道在XXX上设置什么。
我通过以下类似的方式修复它:
public static String nextString() {
StringBuilder randomString = new StringBuilder();
IntStream.range(0, stringLenght).forEach(i -> randomString.append(getRandomChar()));
return randomString.toString();
}
但是我不希望每次使用该方法时都不创建新的StringBuilder,并为简单的方法保留状态和变量。
答案 0 :(得分:4)
这样的事情:
public static String nextString() {
return IntStream.range(0, 10).boxed().map(i -> getRandomChar(i)).collect(Collectors.joining());
}
private static String getRandomChar(int i) {
return String.valueOf((char)i);
}
答案 1 :(得分:1)
不清楚getRandomChar()
是什么值得围绕它构建另一个Stream操作。首先流式传输随机值要简单得多。
,例如,以下代码生成由A-Z
范围内的大写字母组成的随机字符串:
public static String nextString() {
return ThreadLocalRandom.current().ints(stringLength, 'A', 'Z'+1)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
如果目标字符不形成连续范围,则可以使用字符串常量命名允许的字符,例如
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();
}
当然,这个收集器不会以同样的方式隐藏StringBuilder
Collectors.joining()
,但另一方面,此操作没有装箱开销,也不会创建临时字符串。
您可以使用类似的操作来构建字符池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();
}
或者,向读者挑战随机字符串:
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();
}