首先需要一个拥有两个属性的对象Pair,key 和 value
//: net/mindview/util/Pair.java
package net.mindview.util;
public class Pair<K, V> {
public final K key;
public final V value;
public Pair(K k, V v) {
key = k;
value = v;
}
} // /:~
以各种不同的方式,生成MAP对象
//: net/mindview/util/MapData.java
// A Map filled with data using a generator object.
package net.mindview.util;
import java.util.*;
public class MapData<K, V> extends LinkedHashMap<K, V> {
// A single Pair Generator:
public MapData(Generator<Pair<K, V>> gen, int quantity) {
for (int i = 0; i < quantity; i++) {
Pair<K, V> p = gen.next();
put(p.key, p.value);
}
}
// Two separate Generators:
public MapData(Generator<K> genK, Generator<V> genV, int quantity) {
for (int i = 0; i < quantity; i++) {
put(genK.next(), genV.next());
}
}
// A key Generator and a single value:
public MapData(Generator<K> genK, V value, int quantity) {
for (int i = 0; i < quantity; i++) {
put(genK.next(), value);
}
}
// An Iterable and a value Generator:
public MapData(Iterable<K> genK, Generator<V> genV) {
for (K key : genK) {
put(key, genV.next());
}
}
// An Iterable and a single value:
public MapData(Iterable<K> genK, V value) {
for (K key : genK) {
put(key, value);
}
}
// Generic convenience methods:
public static <K, V> MapData<K, V> map(Generator<Pair<K, V>> gen,
int quantity) {
return new MapData<K, V>(gen, quantity);
}
public static <K, V> MapData<K, V> map(Generator<K> genK,
Generator<V> genV, int quantity) {
return new MapData<K, V>(genK, genV, quantity);
}
public static <K, V> MapData<K, V> map(Generator<K> genK, V value,
int quantity) {
return new MapData<K, V>(genK, value, quantity);
}
public static <K, V> MapData<K, V> map(Iterable<K> genK, Generator<V> genV) {
return new MapData<K, V>(genK, genV);
}
public static <K, V> MapData<K, V> map(Iterable<K> genK, V value) {
return new MapData<K, V>(genK, value);
}
} // /:~
分析上面代码,
1、此类继承LinkedHashMap,拥有父类的方法。
2、有5个构造方法,分别以不同的方式初始化,生成对象。
测试类
package containers;
//: containers/MapDataTest.java
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
class Letters implements Generator<Pair<Integer, String>>, Iterable<Integer> {
private int size = 9;
private int number = 1;
private char letter = 'A';
public Pair<Integer, String> next() {
return new Pair<Integer, String>(number++, "" + letter++);
}
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
public Integer next() {
return number++;
}
public boolean hasNext() {
return number < size;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
public class MapDataTest {
public static void main(String[] args) {
// Pair Generator:
print(MapData.map(new Letters(), 11));
// Two separate generators:
print(MapData.map(new CountingGenerator.Character(),
new RandomGenerator.String(3), 8));
// A key Generator and a single value:
print(MapData.map(new CountingGenerator.Character(), "Value", 6));
// An Iterable and a value Generator:
print(MapData.map(new Letters(), new RandomGenerator.String(3)));
// An Iterable and a single value:
print(MapData.map(new Letters(), "Pop"));
}
} /* * Output: {1=A, 2=B, 3=C, 4=D, 5=E, 6=F, 7=G, 8=H, 9=I, 10=J, 11=K} {a=YNz, * b=brn, c=yGc, d=FOW, e=ZnT, f=cQr, g=Gse, h=GZM} {a=Value, b=Value, * c=Value, d=Value, e=Value, f=Value} {1=mJM, 2=RoE, 3=suE, 4=cUO, 5=neO, * 6=EdL, 7=smw, 8=HLG} {1=Pop, 2=Pop, 3=Pop, 4=Pop, 5=Pop, 6=Pop, 7=Pop, * 8=Pop} */// :~
分析上面代码,Letters类实现Generator和Iterable接口
main方法分别调用不同的构造参数,来生成map对象。
“Thinking in java 17.2.2章节”
下面附上一些一来到的代码
//: net/mindview/util/Generator.java
// A generic interface.
package net.mindview.util;
public interface Generator<T> { T next(); } ///:~
//: net/mindview/util/CountingGenerator.java
// Simple generator implementations.
package net.mindview.util;
public class CountingGenerator {
public static class Boolean implements Generator<java.lang.Boolean> {
private boolean value = false;
public java.lang.Boolean next() {
value = !value; // Just flips back and forth
return value;
}
}
public static class Byte implements Generator<java.lang.Byte> {
private byte value = 0;
public java.lang.Byte next() {
return value++;
}
}
static char[] chars = ("abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray();
public static class Character implements Generator<java.lang.Character> {
int index = -1;
public java.lang.Character next() {
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> cg = new Character();
public String() {
}
public String(int length) {
this.length = length;
}
public java.lang.String next() {
char[] buf = new char[length];
for (int i = 0; i < length; i++)
buf[i] = cg.next();
return new java.lang.String(buf);
}
}
public static class Short implements Generator<java.lang.Short> {
private short value = 0;
public java.lang.Short next() {
return value++;
}
}
public static class Integer implements Generator<java.lang.Integer> {
private int value = 0;
public java.lang.Integer next() {
return value++;
}
}
public static class Long implements Generator<java.lang.Long> {
private long value = 0;
public java.lang.Long next() {
return value++;
}
}
public static class Float implements Generator<java.lang.Float> {
private float value = 0;
public java.lang.Float next() {
float result = value;
value += 1.0;
return result;
}
}
public static class Double implements Generator<java.lang.Double> {
private double value = 0.0;
public java.lang.Double next() {
double result = value;
value += 1.0;
return result;
}
}
} // /:~
//: net/mindview/util/RandomGenerator.java
// Generators that produce random values.
package net.mindview.util;
import java.util.*;
public class RandomGenerator {
private static Random r = new Random(47);
public static class Boolean implements Generator<java.lang.Boolean> {
public java.lang.Boolean next() {
return r.nextBoolean();
}
}
public static class Byte implements Generator<java.lang.Byte> {
public java.lang.Byte next() {
return (byte) r.nextInt();
}
}
public static class Character implements Generator<java.lang.Character> {
public java.lang.Character next() {
return CountingGenerator.chars[r
.nextInt(CountingGenerator.chars.length)];
}
}
public static class String extends CountingGenerator.String {
// Plug in the random Character generator:
{
cg = new Character();
} // Instance initializer
public String() {
}
public String(int length) {
super(length);
}
}
public static class Short implements Generator<java.lang.Short> {
public java.lang.Short next() {
return (short) r.nextInt();
}
}
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 next() {
return r.nextInt(mod);
}
}
public static class Long implements Generator<java.lang.Long> {
private int mod = 10000;
public Long() {
}
public Long(int modulo) {
mod = modulo;
}
public java.lang.Long next() {
return new java.lang.Long(r.nextInt(mod));
}
}
public static class Float implements Generator<java.lang.Float> {
public java.lang.Float next() {
// Trim all but the first two decimal places:
int trimmed = Math.round(r.nextFloat() * 100);
return ((float) trimmed) / 100;
}
}
public static class Double implements Generator<java.lang.Double> {
public java.lang.Double next() {
long trimmed = Math.round(r.nextDouble() * 100);
return ((double) trimmed) / 100;
}
}
} // /:~