【发布时间】:2012-04-04 16:43:30
【问题描述】:
您能否推荐一种映射或类似的数据结构,我们可以在其中轻松地从彼此获取值和键。也就是说,每个都可以用来寻找另一个。
【问题讨论】:
-
您可以创建自己的类,其中包含两个 hasmap,每个方向一个,并并行管理它们。明显的缺点是存储空间和性能时间增加了一倍。
标签: java dictionary
您能否推荐一种映射或类似的数据结构,我们可以在其中轻松地从彼此获取值和键。也就是说,每个都可以用来寻找另一个。
【问题讨论】:
标签: java dictionary
基于此 QA 中的 this answer 及其 cmets,我编写了以下内容。 [将被测试]
双向地图
import java.util.HashMap;
public class BidirectionalMap<K, V> extends HashMap<K, V> {
private static final long serialVersionUID = 1L;
public HashMap<V, K> inversedMap = new HashMap<V, K>();
public K getKey(V value) {
return inversedMap.get(value);
}
@Override
public int size() {
return this.size();
}
@Override
public boolean isEmpty() {
return this.size() > 0;
}
@Override
public V remove(Object key) {
V val=super.remove(key);
inversedMap.remove(val);
return val;
}
@Override
public V get(Object key) {
return super.get(key);
}
@Override
public V put(K key, V value) {
inversedMap.put(value, key);
return super.put(key, value);
}
}
【讨论】:
您可以定义一个枚举并定义辅助方法来获取密钥。与 BidiMap 相比,性能要好得多。 例如
public enum Fruit {
APPLE("_apple");
private final String value;
Fruit(String value){
this.value=value;
}
public String getValue(){
return this.value;
}
public static String getKey(String value){
Fruit fruits[] = Fruit.values();
for(Fruit fruit : fruits){
if(value.equals(fruit.value)){
return fruit.name();
}
}
return null; }
}
【讨论】:
Java 在其标准库中没有双向映射。
例如使用来自Google Guava 的BiMap<K, V>。
【讨论】:
Google Guava 包含一个BiMap(双向映射)。
【讨论】:
如果您觉得导入一些第三方库很痛苦。 这个简单的课程怎么样。
public class BiMap<K,V> {
HashMap<K,V> map = new HashMap<K, V>();
HashMap<V,K> inversedMap = new HashMap<V, K>();
void put(K k, V v) {
map.put(k, v);
inversedMap.put(v, k);
}
V get(K k) {
return map.get(k);
}
K getKey(V v) {
return inversedMap.get(v);
}
}
确保 K 和 V 类具有正确的 hashCode 实现。
【讨论】:
HashMap 扩展并在内部保留一个反转映射。然后覆盖所有进行突变的方法,并通过值添加相应的方法进行检索。
对于需要这样的字典的一般用例,我认为 KISS 解决方案没有任何问题,只需将键和值反之亦然,节省第二个 Map 甚至为此目的的库的开销:
myMap.put("apple", "Apfel");
myMap.put("Apfel", "apple");
【讨论】:
也可以试试 Apache Commons Collections 4 BidiMap 包。
【讨论】:
最常见的解决方案是使用两张地图。您可以通过扩展AbstractMap 轻松地将它们封装在具有友好接口的类中。 (更新:这就是 Guava 的 HashBiMap 的实现方式:两张地图)
只使用数组和自定义类来创建新的数据结构几乎没有什么优势。映射实现是索引键的数据结构的轻量级包装器。由于您需要两个索引,因此您不妨使用两个完整的地图。
【讨论】: