使用 Streams 生成随机字符串
创建随机 Strings
有时很有用,可能是作为 Web 服务的 Session-ID 或注册应用程序后的初始密码。这可以使用 Stream
s 轻松实现。
首先,我们需要初始化一个随机数生成器。为了增强生成的 String
s 的安全性,使用 SecureRandom
是个好主意。
注意 :创建 SecureRandom
是非常昂贵的,所以最好只做一次并且不时调用其中一种 setSeed()
方法来重新种植它。
private static final SecureRandom rng = new SecureRandom(SecureRandom.generateSeed(20));
//20 Bytes as a seed is rather arbitrary, it is the number used in the JavaDoc example
在创建随机 String
时,我们通常希望它们仅使用某些字符(例如,仅字母和数字)。因此,我们可以创建一个返回 boolean
的方法,以后可以用来过滤 Stream
。
//returns true for all chars in 0-9, a-z and A-Z
boolean useThisCharacter(char c){
//check for range to avoid using all unicode Letter (e.g. some chinese symbols)
return c >= '0' && c <= 'z' && Character.isLetterOrDigit(c);
}
接下来,我们可以利用 RNG 生成一个特定长度的随机字符串,其中包含通过 useThisCharacter
检查的字符集。
public String generateRandomString(long length){
//Since there is no native CharStream, we use an IntStream instead
//and convert it to a Stream<Character> using mapToObj.
//We need to specify the boundaries for the int values to ensure they can safely be cast to char
Stream<Character> randomCharStream = rng.ints(Character.MIN_CODE_POINT, Character.MAX_CODE_POINT).mapToObj(i -> (char)i).filter(c -> this::useThisCharacter).limit(length);
//now we can use this Stream to build a String utilizing the collect method.
String randomString = randomCharStream.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString();
return randomString;
}