2011-07-04 59 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。

另外,想一想(并在界面中指定它):如果用户插入一个已有值的新密钥会发生什么 - 这是否会失败,被忽略,删除现有的映射或什么?