我需要一个数据结构来存储字符串-整数值对,这些值之间是1:1的关系,并且能够从任意一方查找对应项。
我编写了一个包含哈希表和字符串数组的类,并将数据存储了两次,并使用内置函数进行查找。
我的问题是,有没有更好的方法实现这个需求?更好的意思是既高效又不用存储两次数据,最好也不需要写太多代码 :P。
我需要一个数据结构来存储字符串-整数值对,这些值之间是1:1的关系,并且能够从任意一方查找对应项。
我编写了一个包含哈希表和字符串数组的类,并将数据存储了两次,并使用内置函数进行查找。
我的问题是,有没有更好的方法实现这个需求?更好的意思是既高效又不用存储两次数据,最好也不需要写太多代码 :P。
看起来您可能正在寻找一个双向映射表。
根据BiMap
的文档:
bimap(或“双向映射表”)是一种保留其值唯一性和键唯一性的映射表。此约束使得双向映射表能够支持“反向视图”,即另一个双向映射表,其中包含与此双向映射表相同的条目,但具有反转的键和值。
BiMap.inverse
方法似乎返回一个Map
,其值作为键,键作为值,这样可以使用Map
调用get
获得键。
此外,inverse
方法返回的Map
是基于底层数据的视图,因此无需复制原始数据。
从BiMap.inverse
方法的文档中可以了解到:
返回此bimap的反向视图,将此bimap的每个值映射到其关联键。这两个双向映射表都由相同的数据支持;对一个映射表所做的任何更改都将出现在另一个映射表中。
你可以这样简单地实现。请注意,数据在此实现中未被复制,只有引用!我已添加了add和get的实现。remove和其他所需方法留作练习 :)
public class TwoWayHashmap<K extends Object, V extends Object> {
private Map<K,V> forward = new Hashtable<K, V>();
private Map<V,K> backward = new Hashtable<V, K>();
public synchronized void add(K key, V value) {
forward.put(key, value);
backward.put(value, key);
}
public synchronized V getForward(K key) {
return forward.get(key);
}
public synchronized K getBackward(V key) {
return backward.get(key);
}
}
当然,确保“值”唯一性是应用程序的责任。 示例用法:
TwoWayHashmap twmap = new TwoWayHashmap<String, String>();
twmap.add("aaa", "bbb");
twmap.add("xxx", "yyy");
System.out.println(twmap.getForward("xxx"));
System.out.println(twmap.getBackward("bbb"));
Apache Commons 还包含BidiMap(双向映射)。
定义了一种允许在键和值之间进行双向查找的映射。
这个扩展 Map 表示一种映射,其中一个键可以轻松查找一个值,一个值也可以轻松查找一个键。该接口扩展了 Map 接口,因此可在任何需要 Map 的地方使用。该接口提供了一个反转的映射视图,使得完全可以访问 BidiMap 的两个方向。
Google Guava拥有一个BiMap,可以实现您想要的功能。
一定不需要写很多代码 → 使用lambda
从您的 Map<String,Integer> map
中,您可以通过以下方式获得反转后的映射:
Map<Integer,String> inverted = map.keySet().stream().collect(Collectors.toMap( s -> map.get( s ), s -> s ) );