You are too twisted, -)
Random random = new Random(); String randomString=random.ints(16, 0, 26*2).map(i->(i>=26? 'a'-26: 'A')+i) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) .toString();
Since you already have a source of random values, it makes no sense to call a shuffle function (which does not work well with threads).
Note that you can also explicitly define valid characters in String and select them using: random.ints(16, 0, allowed.length()).map(allowed::charAt)
A similar pattern is used to select from random access List .
Update. If you want the code to clearly show the nature of valid characters in two ranges, you can combine your Stream.concat approach with the char decision described above:
StringBuilder allowed= IntStream.concat(IntStream.rangeClosed('a', 'z'), IntStream.rangeClosed('A', 'Z')) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append); String randomString=random.ints(16, 0, allowed.length()).map(allowed::charAt) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) .toString();
(Note: I replaced range with rangeClosed , which I suspect matches your original intentions until it does what Random.ints(…, 'a', 'z') will do Random.ints(…, 'a', 'z') ).
source share