ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 随机生成 我们可以按照 **Count.java** 的结构创建一个生成随机值的工具: ```java // onjava/Rand.java // (c)2017 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. // Generate random values of different types package onjava; import java.util.*; import java.util.function.*; import static onjava.ConvertTo.*; public interface Rand { int MOD = 10_000; class Boolean implements Supplier<java.lang.Boolean> { SplittableRandom r = new SplittableRandom(47); @Override public java.lang.Boolean get() { return r.nextBoolean(); } public java.lang.Boolean get(int n) { return get(); } public java.lang.Boolean[] array(int sz) { java.lang.Boolean[] result = new java.lang.Boolean[sz]; Arrays.setAll(result, n -> get()); return result; } } class Pboolean { public boolean[] array(int sz) { return primitive(new Boolean().array(sz)); } } class Byte implements Supplier<java.lang.Byte> { SplittableRandom r = new SplittableRandom(47); @Override public java.lang.Byte get() { return (byte)r.nextInt(MOD); } public java.lang.Byte get(int n) { return get(); } public java.lang.Byte[] array(int sz) { java.lang.Byte[] result = new java.lang.Byte[sz]; Arrays.setAll(result, n -> get()); return result; } } class Pbyte { public byte[] array(int sz) { return primitive(new Byte().array(sz)); } } class Character implements Supplier<java.lang.Character> { SplittableRandom r = new SplittableRandom(47); @Override public java.lang.Character get() { return (char)r.nextInt('a', 'z' + 1); } public java.lang.Character get(int n) { return get(); } public java.lang.Character[] array(int sz) { java.lang.Character[] result = new java.lang.Character[sz]; Arrays.setAll(result, n -> get()); return result; } } class Pchar { public char[] array(int sz) { return primitive(new Character().array(sz)); } } class Short implements Supplier<java.lang.Short> { SplittableRandom r = new SplittableRandom(47); @Override public java.lang.Short get() { return (short)r.nextInt(MOD); } public java.lang.Short get(int n) { return get(); } public java.lang.Short[] array(int sz) { java.lang.Short[] result = new java.lang.Short[sz]; Arrays.setAll(result, n -> get()); return result; } } class Pshort { public short[] array(int sz) { return primitive(new Short().array(sz)); } } class Integer implements Supplier<java.lang.Integer> { SplittableRandom r = new SplittableRandom(47); @Override public java.lang.Integer get() { return r.nextInt(MOD); } public java.lang.Integer get(int n) { return get(); } public java.lang.Integer[] array(int sz) { int[] primitive = new Pint().array(sz); java.lang.Integer[] result = new java.lang.Integer[sz]; for(int i = 0; i < sz; i++) result[i] = primitive[i]; return result; } } class Pint implements IntSupplier { SplittableRandom r = new SplittableRandom(47); @Override public int getAsInt() { return r.nextInt(MOD); } public int get(int n) { return getAsInt(); } public int[] array(int sz) { return r.ints(sz, 0, MOD).toArray(); } } class Long implements Supplier<java.lang.Long> { SplittableRandom r = new SplittableRandom(47); @Override public java.lang.Long get() { return r.nextLong(MOD); } public java.lang.Long get(int n) { return get(); } public java.lang.Long[] array(int sz) { long[] primitive = new Plong().array(sz); java.lang.Long[] result = new java.lang.Long[sz]; for(int i = 0; i < sz; i++) result[i] = primitive[i]; return result; } } class Plong implements LongSupplier { SplittableRandom r = new SplittableRandom(47); @Override public long getAsLong() { return r.nextLong(MOD); } public long get(int n) { return getAsLong(); } public long[] array(int sz) { return r.longs(sz, 0, MOD).toArray(); } } class Float implements Supplier<java.lang.Float> { SplittableRandom r = new SplittableRandom(47); @Override public java.lang.Float get() { return (float)trim(r.nextDouble()); } public java.lang.Float get(int n) { return get(); } public java.lang.Float[] array(int sz) { java.lang.Float[] result = new java.lang.Float[sz]; Arrays.setAll(result, n -> get()); return result; } } class Pfloat { public float[] array(int sz) { return primitive(new Float().array(sz)); } } static double trim(double d) { return ((double)Math.round(d * 1000.0)) / 100.0; } class Double implements Supplier<java.lang.Double> { SplittableRandom r = new SplittableRandom(47); @Override public java.lang.Double get() { return trim(r.nextDouble()); } public java.lang.Double get(int n) { return get(); } public java.lang.Double[] array(int sz) { double[] primitive = new Rand.Pdouble().array(sz); java.lang.Double[] result = new java.lang.Double[sz]; for(int i = 0; i < sz; i++) result[i] = primitive[i]; return result; } } class Pdouble implements DoubleSupplier { SplittableRandom r = new SplittableRandom(47); @Override public double getAsDouble() { return trim(r.nextDouble()); } public double get(int n) { return getAsDouble(); } public double[] array(int sz) { double[] result = r.doubles(sz).toArray(); Arrays.setAll(result, n -> result[n] = trim(result[n])); return result; } } class String implements Supplier<java.lang.String> { SplittableRandom r = new SplittableRandom(47); private int strlen = 7; // Default length public String() {} public String(int strLength) { strlen = strLength; } @Override public java.lang.String get() { return r.ints(strlen, 'a', 'z' + 1) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString(); } public java.lang.String get(int n) { return get(); } public java.lang.String[] array(int sz) { java.lang.String[] result = new java.lang.String[sz]; Arrays.setAll(result, n -> get()); return result; } } } ``` 对于除了 **int** 、 **long** 和 **double** 之外的所有基本类型元素生成器,只生成数组,而不是 Count 中看到的完整操作集。这只是一个设计选择,因为本书不需要额外的功能。 下面是对所有 **Rand** 工具的测试: ```java // arrays/TestRand.java // Test random generators import java.util.*; import java.util.stream.*; import onjava.*; import static onjava.ArrayShow.*; public class TestRand { static final int SZ = 5; public static void main(String[] args) { System.out.println("Boolean"); Boolean[] a1 = new Boolean[SZ]; Arrays.setAll(a1, new Rand.Boolean()::get); show(a1); a1 = Stream.generate(new Rand.Boolean()) .limit(SZ + 1).toArray(Boolean[]::new); show(a1); a1 = new Rand.Boolean().array(SZ + 2); show(a1); boolean[] a1b = new Rand.Pboolean().array(SZ + 3); show(a1b); System.out.println("Byte"); Byte[] a2 = new Byte[SZ]; Arrays.setAll(a2, new Rand.Byte()::get); show(a2); a2 = Stream.generate(new Rand.Byte()) .limit(SZ + 1).toArray(Byte[]::new); show(a2); a2 = new Rand.Byte().array(SZ + 2); show(a2); byte[] a2b = new Rand.Pbyte().array(SZ + 3); show(a2b); System.out.println("Character"); Character[] a3 = new Character[SZ]; Arrays.setAll(a3, new Rand.Character()::get); show(a3); a3 = Stream.generate(new Rand.Character()) .limit(SZ + 1).toArray(Character[]::new); show(a3); a3 = new Rand.Character().array(SZ + 2); show(a3); char[] a3b = new Rand.Pchar().array(SZ + 3); show(a3b); System.out.println("Short"); Short[] a4 = new Short[SZ]; Arrays.setAll(a4, new Rand.Short()::get); show(a4); a4 = Stream.generate(new Rand.Short()) .limit(SZ + 1).toArray(Short[]::new); show(a4); a4 = new Rand.Short().array(SZ + 2); show(a4); short[] a4b = new Rand.Pshort().array(SZ + 3); show(a4b); System.out.println("Integer"); int[] a5 = new int[SZ]; Arrays.setAll(a5, new Rand.Integer()::get); show(a5); Integer[] a5b = Stream.generate(new Rand.Integer()) .limit(SZ + 1).toArray(Integer[]::new); show(a5b); a5b = new Rand.Integer().array(SZ + 2); show(a5b); a5 = IntStream.generate(new Rand.Pint()) .limit(SZ + 1).toArray(); show(a5); a5 = new Rand.Pint().array(SZ + 3); show(a5); System.out.println("Long"); long[] a6 = new long[SZ]; Arrays.setAll(a6, new Rand.Long()::get); show(a6); Long[] a6b = Stream.generate(new Rand.Long()) .limit(SZ + 1).toArray(Long[]::new); show(a6b); a6b = new Rand.Long().array(SZ + 2); show(a6b); a6 = LongStream.generate(new Rand.Plong()) .limit(SZ + 1).toArray(); show(a6); a6 = new Rand.Plong().array(SZ + 3); show(a6); System.out.println("Float"); Float[] a7 = new Float[SZ]; Arrays.setAll(a7, new Rand.Float()::get); show(a7); a7 = Stream.generate(new Rand.Float()) .limit(SZ + 1).toArray(Float[]::new); show(a7); a7 = new Rand.Float().array(SZ + 2); show(a7); float[] a7b = new Rand.Pfloat().array(SZ + 3); show(a7b); System.out.println("Double"); double[] a8 = new double[SZ]; Arrays.setAll(a8, new Rand.Double()::get); show(a8); Double[] a8b = Stream.generate(new Rand.Double()) .limit(SZ + 1).toArray(Double[]::new); show(a8b); a8b = new Rand.Double().array(SZ + 2); show(a8b); a8 = DoubleStream.generate(new Rand.Pdouble()) .limit(SZ + 1).toArray(); show(a8); a8 = new Rand.Pdouble().array(SZ + 3); show(a8); System.out.println("String"); String[] s = new String[SZ - 1]; Arrays.setAll(s, new Rand.String()::get); show(s); s = Stream.generate(new Rand.String()) .limit(SZ).toArray(String[]::new); show(s); s = new Rand.String().array(SZ + 1); show(s); Arrays.setAll(s, new Rand.String(4)::get); show(s); s = Stream.generate(new Rand.String(4)) .limit(SZ).toArray(String[]::new); show(s); s = new Rand.String(4).array(SZ + 1); show(s); } } /* Output: Boolean [true, false, true, true, true] [true, false, true, true, true, false] [true, false, true, true, true, false, false] [true, false, true, true, true, false, false, true] Byte [123, 33, 101, 112, 33] [123, 33, 101, 112, 33, 31] [123, 33, 101, 112, 33, 31, 0] [123, 33, 101, 112, 33, 31, 0, -72] Character [b, t, p, e, n] [b, t, p, e, n, p] [b, t, p, e, n, p, c] [b, t, p, e, n, p, c, c] Short [635, 8737, 3941, 4720, 6177] [635, 8737, 3941, 4720, 6177, 8479] [635, 8737, 3941, 4720, 6177, 8479, 6656] [635, 8737, 3941, 4720, 6177, 8479, 6656, 3768] Integer [635, 8737, 3941, 4720, 6177] [635, 8737, 3941, 4720, 6177, 8479] [635, 8737, 3941, 4720, 6177, 8479, 6656] [635, 8737, 3941, 4720, 6177, 8479] [635, 8737, 3941, 4720, 6177, 8479, 6656, 3768] Long [6882, 3765, 692, 9575, 4439] [6882, 3765, 692, 9575, 4439, 2638] [6882, 3765, 692, 9575, 4439, 2638, 4011] [6882, 3765, 692, 9575, 4439, 2638] [6882, 3765, 692, 9575, 4439, 2638, 4011, 9610] Float [4.83, 2.89, 2.9, 1.97, 3.01] [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] [4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99] [4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99, 8.28] Double [4.83, 2.89, 2.9, 1.97, 3.01] [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] [4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99] [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] [4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99, 8.28] String [btpenpc, cuxszgv, gmeinne, eloztdv] [btpenpc, cuxszgv, gmeinne, eloztdv, ewcippc] [btpenpc, cuxszgv, gmeinne, eloztdv, ewcippc, ygpoalk] [btpe, npcc, uxsz, gvgm, einn, eelo] [btpe, npcc, uxsz, gvgm, einn] [btpe, npcc, uxsz, gvgm, einn, eelo] */ ``` 注意(除了 **String** 部分之外),这段代码与 **TestCount.java** 中的代码相同,**Count** 被 **Rand** 替换。