使用 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;
}