要生成不同類型的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生成器還有很多值得鑽研的地方,等有時間再好好研究一番。