我实施了一张独特的地图。它是一个双向的散列图,其中不仅键是唯一的,而且值也是值。
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;
}
}
正如您所看到的,我已经尝试为我的唯一地图实现迭代器。但是从散列映射中,值不是按位置访问,而是按键访问。所以通常我会拿计数器和访问值,但在这种情况下它不可能。
实际上,迭代密钥并逐个检索它们就足够了。我怎样才能做到这一点?有没有办法检索包含键和值的某种入口对象?
我知道我可以从地图对象中检索迭代器,但这对我来说不是一个选项。
答案 0 :(得分:3)
更新:最简单的是,使用
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>
它已经为地图提供了很多基本功能。
答案 1 :(得分:2)
你可以通过简单地委托你的支持hashmap的keyset迭代器来实现你的iterator()
方法:
public Iterator<K> iterator(){
return uniqueMap.keySet().iterator();
}
当然,正如Lukas所说,通常地图不会是可迭代的,但提供的集合视图本身是可迭代的。
此外,您的独特地图实施可能会在两个方向都有HashMaps。
另外,请考虑(并在界面中指定它):如果用户插入一个已存在的值的新密钥会发生什么 - 这是否会失败,被忽略,删除现有的映射,还是什么?
答案 2 :(得分:1)
您应该查看Guava library(Google Collection)。他们有一个BiMap实现,似乎正是你想要实现的......