【问题标题】:How to create a custom iterator for a Map implementation?如何为 Map 实现创建自定义迭代器?
【发布时间】:2011-07-04 12:15:40
【问题描述】:

我实现了一个独特的地图。它是一个双向的 hashmap,其中不仅键是唯一的,而且值也是唯一的。

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;
    }
}

如您所见,我已经尝试为我的独特地图实现迭代器。但是从哈希图中,值不是按位置访问的,而是按键访问的。所以通常我会采用计数器和访问值,但在这种情况下它是不可能的。

实际上,遍历键并逐个检索它们就足够了。我怎样才能做到这一点?有没有办法检索某种同时包含键和值的条目对象?

我知道我可以从地图对象中检索迭代器,但这不是我的选择。

【问题讨论】:

    标签: java hashmap


    【解决方案1】:

    更新:最简单的,使用

    org.apache.commons.collections.BidiMap
    

    但如果你真的想自己动手,那么考虑一下:

    通常,Maps 不实现 Iterable。在你的情况下,你可以通过拨打这些电话免费获得Iterator

    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();
    

    在您的地图上,具体取决于您要迭代的内容。为此,您必须制作

    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();
      }
      

      当然,正如 Lukas 所说,通常地图不会是可迭代的,但会提供本身可迭代的集合视图。

      此外,对于您的独特地图实现,在两个方向上都有 HashMap 可能是个好主意。

      另外,请考虑(并在界面中指定它):如果用户插入具有现有值的新键会发生什么 - 这会失败、被忽略、删除现有映射还是什么?

      【讨论】:

        【解决方案3】:

        你应该看看Guava library(谷歌收藏)。他们有一个BiMap 实现,这似乎正是您想要实现的......

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-09
          • 2018-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-14
          相关资源
          最近更新 更多