Философия Java3
Шрифт:
}
}
public static class
Byte implements Generator<java lang Byte> { public java lang Byte nextO {
return (byte)r nextlntO;
}
}
public static class
Character implements Generator<java.lang Character { public java lang Character nextO {
return CountingGenerator.charsE
r nextInt(CountingGenerator.chars.length)],
}
}
public static class
String extends CountingGenerator.String {
// Подключение случайного генератора Character { eg = new CharacterO; } //
public String(int length) { super(1ength), }
}
public static class
Short implements Generator<java.lang Short> { public java.lang Short nextO {
return (short)r.nextlntO.
}
}
public static class
Integer implements Generator<java lang.Integer> { private int mod = 10000; public IntegerО {}
public Integer(int modulo) { mod = modulo; } public java lang Integer nextO { return r.nextlnt(mod);
}
}
public static class
Long implements Generator<java.lang.Long> { private int mod = 10000. public LongO {}
public Long(int modulo) { mod = modulo; } public java lang.Long nextO {
return new java.lang.Long(r nextInt(mod));
}
}
public static class
Float implements Generator<java lang Float> { public java.lang.Float nextO {
// Отсечение до двух разрядов в дробной части, int trimmed = Math.round(r nextFloatO * 100). return ((float)trimmed) / 100.
}
} ///:-
Как видите, RandomGenerator.String наследует от CountingGenerator.String, просто подключая новый генератор Character.
Чтобы генерируемые числа были не слишком велики, RandomGenerator. Integer по умолчанию берет остаток от деления на 10 ООО, но перегруженный конструктор позволяет выбрать меньшее значение. Аналогичный подход используется и для RandomGenerator.Long. Для генераторов Float и Double цифры в дробной части усекаются.
Для тестирования RandomGenerator можно воспользоваться уже готовым классом GeneratorsTest:
//: arrays/RandomGeneratorsTest.java import net.mindview util.*;
public class RandomGeneratorsTest {
public static void main(String[] args) {
GeneratorsTest test(RandomGenerator.class);
}
} /* Output:
Double: 0.73 0.53 0.16 0 19 0.52 0.27 0.26 0.05 0.8 0.76 Float: 0.53 0,16 0.53 0.4 0.49 0.25 0.8 0.11 0.02 0.8 Long: 7674 8804 8950 7826 4322 896 8033 2984 2344 5810 Integer: 8303 3141 7138 6012 9966 8689 7185 6992 5746 3976 Short: 3358 20592 284 26791 12834 -8092 13656 29324 -1423 5327
String: bklnaMe sbtWHkj UrUkZPg wsqPzDy CyRFJQA HxxHvHq XumcXZJ oogoYWM NvqeuTp nXsgqia Character: xxEAJJmzMs Byte: -60 -17 55 -14 -5 115 39 -37 79 115 Boolean: false true false false true true true true true true *///:-
Чтобы изменить количество генерируемых значений, воспользуйтесь public-полем GeneratorsTest.size.
Создание массивов
Для создания массивов на основе Generator нам потребуются два вспомогательных класса. Первый использует произвольный Generator для получения массива типов, производных от Object. Для решения проблемы с примитивами второй класс получает произвольный массив с объектами-«обертками» и строит для него соответствующий массив примитивов.
Первый вспомогательный класс может работать в двух режимах, представленных перегруженным статическим методом аггау. Первая версия метода получает существующий массив и заполняет его с использованием Generator; вторая версия получает объект Class, Generator и количество элементов и создает новый массив, который также заполняется с использованием Generator. Помните, что при этом создаются только массивы субтипов Object, но не массивы примитивных типов:
public static class
Double implements Generator<java.lang.Double> { public java.lang.Double nextO {
long trimmed = Math.round(r.nextDouble * 100); return ((double)trimmed) / 100;
//• net/mi ndvi ew/uti1/Generated.java package net.mi ndvi ew.uti1, import java.util.*;
public class Generated {
II Заполнение существующего массива:
public static <T> T[] array(T[] a. Generator<T> gen) {
return new CollectionData<T>(gen, a.length).toArray(a):
}
// Создание нового массива: @SuppressWarnings("unchecked") public static <T> T[] array(Class<T> type. Generator<T> gen. int size) { T[] a =
(T[])java.1ang.ref1ect.Array.newlnstance(type. size); return new CollectionData<T>(gen. size) toArray(a);
}
} ///:-
Класс Collection Data создает объект Collection, заполненный элементами, которые были созданы генератором gen. Количество элементов определяется вторым аргументом конструктора. Все субтипы Collection содержат метод toArray, заполняющий массив-аргумент элементами из Collection.
Второй метод использует рефлексию для динамического создания нового массива соответствующего типа и размера. Затем созданный массив заполняется таким же способом, как в первом методе.
Чтобы протестировать Generated, мы воспользуемся одним из классов CountingGenerator, описанных в предыдущем разделе:
II: arrays/TestGenerated.java import java.util.*; import net.mindview util.*:
public class TestGenerated {
public static void main(String[] args) { Integer[] a = { 9. 8. 7. 6 }: System.out.pri ntin(Arrays.toStri ng(a)); a = Generated, array (a, new CountingGenerator.IntegerO); System. out. pri nti n( Arrays. toStri ng(a)): Integer[] b = Generated.array(Integer.class.