要生成不同类型的map,需要用到生成器接口,泛型,首先定义一个pair关联对象类
package com;
public class Pair<K,V> {
public final K key;
public final V value;
public Pair(K k,V v)
{
this.key=k;
this.value=v;
}
}
这是一个基本类,K和V是有一定对应关系的,具体关系需要在具体业务需求中才能体现出来,然后定义一个mapdata(继承自linkedhashmap),就是需要的map生成器
,这个生成器类需要用到生成器(Gernerator<T>类),因此还需要定义一个接口Gernerator<T>
package com;
public interface Gernerator<T> {
T next();
}
这是一个接口,里面有一个为实现的方法,next(),如果继承这个接口的类需要实现这个接口中的方法,map生成器类如下:
package com;
import java.util.LinkedHashMap;
public class MapData<K,V> extends LinkedHashMap<K, V> {
public MapData(Gernerator<Pair<K,V>> gen,int n)
{
for(int i=0;i<n;i++)
{
Pair<K, V> p=gen.next();
put(p.key,p.value);//隐藏了this关键字,应该是this.put,因为这个构造器生成的类对象继承自hashmap
}
}
public MapData(Gernerator<K> genk,Gernerator<V> genv,int n)
{
for(int i=0;i<n;i++)
{
put(genk.next(),genv.next());//next就是生成一个类对象,这个类对象是k或者v类型的,这点一定要明确
}
}
public MapData(Gernerator<K> genk,V value,int n)
{
for(int i=0;i<n;i++)
{
put(genk.next(),value);
}
}
public MapData(K k,Gernerator<V> genv,int n)
{
for(int i=0;i<n;i++)
{
put(k,genv.next());
}
}
public MapData(Iterable<K> genk,Gernerator<V> genv)
{
for(K k:genk)
{
put(k,genv.next());
}
}
public MapData(Iterable<K> genk,V value)
{
for(K k:genk)
{
put(k,value);
}
}
public static <K,V> MapData<K, V> map(Gernerator<Pair<K, V>> gen,int n)
{
return new MapData<K, V>(gen,n);
}
public static <K,V> MapData<K, V> map(Gernerator<K> genk,Gernerator<V> genv,int n)
{
return new MapData<K, V>(genk,genv, n);
}
public static <K,V> MapData<K, V> map(Gernerator<K> genk,V value,int n)
{
return new MapData<K, V>(genk, value,n);
}
public static <K,V> MapData<K, V> map(Iterable<K> genk,Gernerator<V> value)
{
return new MapData<K, V>(genk, value);
}
public static <K,V> MapData<K, V> map(Iterable<K> key,V value)
{
return new MapData<K, V>(key,value);
}
}
这个map生成器有几个不同参数的构造方法,应用于不同类型的map生成,还有五个对应的静态map方法,用来生成mapdata对象,其实实质上是一个hashmap
这里为了测试,自己写了一个类(实现上面的生成器接口和iterable),方便测试验证
package com;
import java.util.Iterator;
public class letters implements Gernerator<Pair<Integer,String>>,Iterable<Integer>{
private int number=0;
private int size=9;
private char letter='A';
@Override
public Iterator<Integer> iterator() {
// TODO Auto-generated method stub
return new Iterator<Integer>() {
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return number<size;
}
@Override
public Integer next() {
// TODO Auto-generated method stub
return number++;
}
@Override
public void remove() {
// TODO Auto-generated method stub
}
};
}
@Override
public Pair<Integer, String> next() {
// TODO Auto-generated method stub
return new Pair<Integer,String>(number++,""+letter++);
}
}
这个类其实很重要,这里继承了两个接口,一个为自己定义的生成器接口,一个为iterable接口,必须实现接口的相应方法,iterale接口必须实现iterator<T> iterator()接口
这个接口里面有一个类部类,这个类部类里面必须实现三个方法,一个为next(),一个为hasnext(),一个为remove(),基本上继承iterable<T>的都要实现这个基本类部类,这个类部类形式都是这样子的,只需要根据自己的需求写一些必须的成员变量,重写一下三种方法,就可以,一般是实现next()和hasnext(),根据自己需要调整,
一般next()方法里面的一些计数值会累加,hasnext()方法会比较两个计数值的大小返回一个bool值,这样就实现了letters类,这个类从一定意义上是一个生成器
然后就可以写main方法,测试这个map生成器了:
package com;
public class MapDatatest {
public static void main(String[] args) {
System.out.println(MapData.map(new letters(),11));
}
}
首先生成letters类,这个map生成器对象会自动去找寻匹配的那个map方法,最后发现生成的letter更多的是gernerator属性,因此,会对其pair类,因此,输出结果如下所示:
{0=A, 1=B, 2=C, 3=D, 4=E, 5=F, 6=G, 7=H, 8=I, 9=J, 10=K}
这个map生成器还有很多值得钻研的地方,等有时间再好好研究一番。