ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
## 增量生成 这是一个方法库,用于为不同类型生成增量值。 这些被作为内部类来生成容易记住的名字;比如,为了使用 **Integer** 工具你可以用 **new Conut.Interger()** , 如果你想要使用基本数据类型 **int** 工具,你可以用 **new Count.Pint()** (基本类型的名字不能被直接使用,所以它们都在前面添加一个 **P** 来表示基本数据类型'primitive', 我们的第一选择是使用基本类型名字后面跟着下划线,比如 **int_** 和 **double_** ,但是这种方式违背Java的命名习惯)。每个包装类的生成器都使用 **get()** 方法实现了它的 **Supplier** 。要使用**Array.setAll()** ,一个重载的 **get(int n)** 方法要接受(并忽略)其参数,以便接受 **setAll()** 传递的索引值。 注意,通过使用包装类的名称作为内部类名,我们必须调用 **java.lang** 包来保证我们可以使用实际包装类的名字: ```java // onjava/Count.java // Generate incremental values of different types package onjava; import java.util.*; import java.util.function.*; import static onjava.ConvertTo.*; public interface Count { class Boolean implements Supplier<java.lang.Boolean> { private boolean b = true; @Override public java.lang.Boolean get() { b = !b; return java.lang.Boolean.valueOf(b); } 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 { private boolean b = true; public boolean get() { b = !b; return b; } public boolean get(int n) { return get(); } public boolean[] array(int sz) { return primitive(new Boolean().array(sz)); } } class Byte implements Supplier<java.lang.Byte> { private byte b; @Override public java.lang.Byte get() { return b++; } 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 { private byte b; public byte get() { return b++; } public byte get(int n) { return get(); } public byte[] array(int sz) { return primitive(new Byte().array(sz)); } } char[] CHARS = "abcdefghijklmnopqrstuvwxyz".toCharArray(); class Character implements Supplier<java.lang.Character> { private int i; @Override public java.lang.Character get() { i = (i + 1) % CHARS.length; return CHARS[i]; } 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 { private int i; public char get() { i = (i + 1) % CHARS.length; return CHARS[i]; } public char get(int n) { return get(); } public char[] array(int sz) { return primitive(new Character().array(sz)); } } class Short implements Supplier<java.lang.Short> { short s; @Override public java.lang.Short get() { return s++; } 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 { short s; public short get() { return s++; } public short get(int n) { return get(); } public short[] array(int sz) { return primitive(new Short().array(sz)); } } class Integer implements Supplier<java.lang.Integer> { int i; @Override public java.lang.Integer get() { return i++; } public java.lang.Integer get(int n) { return get(); } public java.lang.Integer[] array(int sz) { java.lang.Integer[] result = new java.lang.Integer[sz]; Arrays.setAll(result, n -> get()); return result; } } class Pint implements IntSupplier { int i; public int get() { return i++; } public int get(int n) { return get(); } @Override public int getAsInt() { return get(); } public int[] array(int sz) { return primitive(new Integer().array(sz)); } } class Long implements Supplier<java.lang.Long> { private long l; @Override public java.lang.Long get() { return l++; } public java.lang.Long get(int n) { return get(); } public java.lang.Long[] array(int sz) { java.lang.Long[] result = new java.lang.Long[sz]; Arrays.setAll(result, n -> get()); return result; } } class Plong implements LongSupplier { private long l; public long get() { return l++; } public long get(int n) { return get(); } @Override public long getAsLong() { return get(); } public long[] array(int sz) { return primitive(new Long().array(sz)); } } class Float implements Supplier<java.lang.Float> { private int i; @Override public java.lang.Float get() { return java.lang.Float.valueOf(i++); } 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 { private int i; public float get() { return i++; } public float get(int n) { return get(); } public float[] array(int sz) { return primitive(new Float().array(sz)); } } class Double implements Supplier<java.lang.Double> { private int i; @Override public java.lang.Double get() { return java.lang.Double.valueOf(i++); } public java.lang.Double get(int n) { return get(); } public java.lang.Double[] array(int sz) { java.lang.Double[] result = new java.lang.Double[sz]; Arrays.setAll(result, n -> get()); return result; } } class Pdouble implements DoubleSupplier { private int i; public double get() { return i++; } public double get(int n) { return get(); } @Override public double getAsDouble() { return get(0); } public double[] array(int sz) { return primitive(new Double().array(sz)); } } } ``` 对于 **int** ,**long** ,**double** 这三个有特殊 **Supplier** 接口的原始数据类型来说,**Pint** , **Plong** 和 **Pdouble** 实现了这些接口。 这里是对 **Count** 的测试,这同样给我们提供了如何使用它的例子: ```java // arrays/TestCount.java // Test counting generators import java.util.*; import java.util.stream.*; import onjava.*; import static onjava.ArrayShow.*; public class TestCount { static final int SZ = 5; public static void main(String[] args) { System.out.println("Boolean"); Boolean[] a1 = new Boolean[SZ]; Arrays.setAll(a1, new Count.Boolean()::get); show(a1); a1 = Stream.generate(new Count.Boolean()) .limit(SZ + 1).toArray(Boolean[]::new); show(a1); a1 = new Count.Boolean().array(SZ + 2); show(a1); boolean[] a1b = new Count.Pboolean().array(SZ + 3); show(a1b); System.out.println("Byte"); Byte[] a2 = new Byte[SZ]; Arrays.setAll(a2, new Count.Byte()::get); show(a2); a2 = Stream.generate(new Count.Byte()) .limit(SZ + 1).toArray(Byte[]::new); show(a2); a2 = new Count.Byte().array(SZ + 2); show(a2); byte[] a2b = new Count.Pbyte().array(SZ + 3); show(a2b); System.out.println("Character"); Character[] a3 = new Character[SZ]; Arrays.setAll(a3, new Count.Character()::get); show(a3); a3 = Stream.generate(new Count.Character()) .limit(SZ + 1).toArray(Character[]::new); show(a3); a3 = new Count.Character().array(SZ + 2); show(a3); char[] a3b = new Count.Pchar().array(SZ + 3); show(a3b); System.out.println("Short"); Short[] a4 = new Short[SZ]; Arrays.setAll(a4, new Count.Short()::get); show(a4); a4 = Stream.generate(new Count.Short()) .limit(SZ + 1).toArray(Short[]::new); show(a4); a4 = new Count.Short().array(SZ + 2); show(a4); short[] a4b = new Count.Pshort().array(SZ + 3); show(a4b); System.out.println("Integer"); int[] a5 = new int[SZ]; Arrays.setAll(a5, new Count.Integer()::get); show(a5); Integer[] a5b = Stream.generate(new Count.Integer()) .limit(SZ + 1).toArray(Integer[]::new); show(a5b); a5b = new Count.Integer().array(SZ + 2); show(a5b); a5 = IntStream.generate(new Count.Pint()) .limit(SZ + 1).toArray(); show(a5); a5 = new Count.Pint().array(SZ + 3); show(a5); System.out.println("Long"); long[] a6 = new long[SZ]; Arrays.setAll(a6, new Count.Long()::get); show(a6); Long[] a6b = Stream.generate(new Count.Long()) .limit(SZ + 1).toArray(Long[]::new); show(a6b); a6b = new Count.Long().array(SZ + 2); show(a6b); a6 = LongStream.generate(new Count.Plong()) .limit(SZ + 1).toArray(); show(a6); a6 = new Count.Plong().array(SZ + 3); show(a6); System.out.println("Float"); Float[] a7 = new Float[SZ]; Arrays.setAll(a7, new Count.Float()::get); show(a7); a7 = Stream.generate(new Count.Float()) .limit(SZ + 1).toArray(Float[]::new); show(a7); a7 = new Count.Float().array(SZ + 2); show(a7); float[] a7b = new Count.Pfloat().array(SZ + 3); show(a7b); System.out.println("Double"); double[] a8 = new double[SZ]; Arrays.setAll(a8, new Count.Double()::get); show(a8); Double[] a8b = Stream.generate(new Count.Double()) .limit(SZ + 1).toArray(Double[]::new); show(a8b); a8b = new Count.Double().array(SZ + 2); show(a8b); a8 = DoubleStream.generate(new Count.Pdouble()) .limit(SZ + 1).toArray(); show(a8); a8 = new Count.Pdouble().array(SZ + 3); show(a8); } } /* Output: Boolean [false, true, false, true, false] [false, true, false, true, false, true] [false, true, false, true, false, true, false] [false, true, false, true, false, true, false, true] Byte [0, 1, 2, 3, 4] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5, 6, 7] Character [b, c, d, e, f] [b, c, d, e, f, g] [b, c, d, e, f, g, h] [b, c, d, e, f, g, h, i] Short [0, 1, 2, 3, 4] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5, 6, 7] Integer [0, 1, 2, 3, 4] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5, 6, 7] Long [0, 1, 2, 3, 4] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5, 6, 7] Float [0.0, 1.0, 2.0, 3.0, 4.0] [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0] [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] Double [0.0, 1.0, 2.0, 3.0, 4.0] [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0] [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] */ ``` 注意到原始数组类型 **int[]** ,**long[]** ,**double[]** 可以直接被 **Arrays.setAll()** 填充,但是其他的原始类型都要求用包装器类型的数组。 通过 **Stream.generate()** 创建的包装数组显示了 **toArray()** 的重载用法,在这里你应该提供给它要创建的数组类型的构造器。