Эккель Брюс
Шрифт:
В этом разделе будут представлены некоторые готовые генераторы, но вы также сможете легко определить собственный генератор для своих потребностей.
Для начала рассмотрим простейший набор счетных генераторов для всех примитивных типов и String. Классы генераторов вложены в класс Counting-Generator, чтобы они могли обозначаться именами генерируемых объектов. Например, генератор, создающий объекты Integer, будет создаваться выражением new CountingGenerator.Integer:
//: net/mi ndvi ew/uti1/Counti ngGenerator.java // Простые реализации генераторов, package net.mi ndvi ew.uti1;
public class CountingGenerator {
public static class
Boolean implements Generatorjava.lang.Boolean> { private boolean value = false; public java.lang.Boolean nextO {
value = lvalue; // Поочередное переключение return value;
}
}
public static class
Byte implements Generator<java.lang.Byte> { private byte value = 0;
public java.lang.Byte nextO { return value++; }
}
static char[] chars = ("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray;
public static class
Character implements Generator<java.lang.Character> { int index = -1;
public java.lang.Character nextO {
index = (index + 1) % chars.length; return chars[index];
}
}
public static class
String implements Generator<java lang String> { private int length = 7;
Generator<java\lang.Character> eg = new CharacterO; public StringO {}
public String(int length) { this.length = length; } public java.lang.String nextO {
char[] buf = new char[length]; for(int i = 0; i < length; i++)
buf[i] = eg.nextO; return new java.lang.String(buf);
}
}
public static class
Short implements Generator<java.lang.Short> { private short value = 0;
public java.lang.Short nextO { return value++; }
}
public static class
Integer implements Generator<java.lang.Integer> { private int value = 0;
public java.lang.Integer nextO { return value++; }
}
public static class
Long implements Generator<java.lang.Long> { private long value = 0;
public java.lang.Long nextO { return value++; }
}
public static class
Float implements Generator<java.lang.Float> { private float value = 0; public java.lang.Float nextO { float result = value; value += 1.0; return result;
}
}
public static class
Double implements Generator java. lang Double> { private double value = O.'O; public java.lang.Double nextO { double result = value; value += 1.0; return result;
}
}
} ///:-
Каждый класс реализует некоторое понятие «счетности». В случае Counting-Generator.Character это повторение символов верхнего и нижнего регистра. Класс CountingGenerator.String использует CountingGenerator.Character для заполнения массива символов, который затем преобразуется в String. Размер массива определяется аргументом конструктора. Обратите внимание на то, что CountingGenerator.String использует базовую конструкцию Generator<java.lang. Character вместо конкретной ссылки на CountingGenerator.Character.
Следующая тестовая программа использует рефлексию с идиомой вложенных генераторов, что позволяет применять ее для любого набора генераторов, построенного по указанному образцу:
//: arrays/GeneratorsTest.java import net.mindview.util.*;
public class GeneratorsTest {
public static int size = 10;
public static void test(Class<?> surroundingClass) {
for(Class<?> type : surroundingClass.getClassesO) {
System.out.print(type.getSimpleName + ": "); try {
Generator<?> g = (Generator<?>)type.newInstance; for(int i = 0; i < size; i++)
System.out printf(g.next + " "); System, out. printlnO; } catch(Exception e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) { test(CountingGenerator.class);
}
} /* Output;
Double; 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 Float; 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 Long; 0 12 3 4 5 6 7 8 9 Integer; 0 1 2 3 4 5 6 7 8 9 Short; 0 12 3 4 5 6 7 8 9