2011-07-04 63 views
4

我實現了一個獨特的地圖。這是一個雙向散列表,其中不僅鍵是唯一的,而且值也是。如何爲Map實現創建自定義迭代器?

public interface UniqueMap<K,V>{ 

    V uniquePut(K key, V value); 

    UniqueMap<V,K> inverse(); 
} 

這是一個可能的實現:

public class SimpleUniqueMap<K,V> implements UniqueMap<K,V>, Iterable<K>{ 

    public HashMap<K,V> uniqueMap = new HashMap<K,V>(); 

    class EnumSimpleUniqueMap implements Iterator<K>{ 

     int count = uniqueMap.size(); 

     public boolean hasNext(){ 
      return count > 0; 
     } 

     public K next(){ 
      if(count == 0){ 
       throw new NoSuchElementException();  
      }else{ 
       count--; 
       //... 
      } 
     } 

     public void remove(){ 
      throw new UnsupportedOperationException(); 
     } 
    } 

    public Iterator<V> iterator(){ 
     return new EnumSimpleUniqueMap(); 
    } 

    public V uniquePut(K key, V value){ 
     return null; 
    } 

    public UniqueMap<V,K> inverse(){ 
     return null; 
    } 
} 

正如你可以看到我已經嘗試實現我的唯一地圖迭代器。但是從一個hashmap值不是由位置訪問,而是由key來訪問。所以通常我會拿櫃檯並獲取價值,但在這種情況下,這不是可能的。

實際上,迭代鍵並逐個檢索它們就足夠了。我怎樣才能做到這一點?有沒有辦法檢索某種包含鍵和值的入口對象?

我知道我可以從地圖對象中檢索迭代器,但這不是我的選擇。

回答

3

UPDATE:最簡單的是,使用

org.apache.commons.collections.BidiMap 

但是,如果你真的想推出自己的,然後再考慮這一點:

通常,Maps沒有實現Iterable。你的情況,你可以通過調用任何這些

map.keys().iterator(); // is the same as 
map.inverse().values().iterator(); 

map.values().iterator(); // is the same as 
map.inverse().keys().iterator(); 

map.entrySet().iterator(); // almost the same as 
map.inverse().entrySet().iterator(); 

你的地圖上,這取決於你想遍歷什麼讓Iterator免費。對於這一點,你就必須做出

public interface UniqueMap<K,V> extends Map<K, V> { 
    // no need for uniquePut(), you already have Map.put() 
    UniqueMap<V,K> inverse(); 
} 

這也是一個好主意,讓您的實現擴展

java.util.AbstractMap<K, V> 

這對於地圖很多基本功能了。

2

您可以通過簡單地委託給你的底層HashMap的鍵集迭代器可以實現您的iterator()方法:

public Iterator<K> iterator(){ 
    return uniqueMap.keySet().iterator(); 
} 

當然,作爲盧卡斯說,平時的地圖將不會迭代,但是提供收集意見,它本身可迭代。

另外,它可能是一個好主意,讓您獨特的地圖實現在兩個方向都有HashMaps。

另外,想一想(並在界面中指定它):如果用戶插入一個已有值的新密鑰會發生什麼 - 這是否會失敗,被忽略,刪除現有的映射或什麼?