【发布时间】:2009-04-02 21:03:11
【问题描述】:
我需要一个可以根据键查找值的集合,反之亦然。每个值都有一个键,每个键都有一个值。是否有现成的数据结构可以做到这一点?
【问题讨论】:
标签: java collections
我需要一个可以根据键查找值的集合,反之亦然。每个值都有一个键,每个键都有一个值。是否有现成的数据结构可以做到这一点?
【问题讨论】:
标签: java collections
Google Guava 中的 BiMap 看起来很适合你。
双映射(或“双向映射”)是一种映射,它保留其值的唯一性以及其键的唯一性。此约束使 bimap 能够支持“反向视图”,这是另一个 bimap,包含与此 bimap 相同的条目,但具有相反的键和值。
或者来自Apache Commons Collections的BidiMap:
定义一个允许键和值之间双向查找的映射。
这个扩展的
Map表示一个映射,其中一个键可以查找一个值,而一个值可以同样容易地查找一个键。这个接口扩展了Map,因此可以在任何需要地图的地方使用。该界面提供了一个反向地图视图,可以完全访问BidiMap的两个方向。
【讨论】:
您可以使用来自Eclipse Collections(以前的GS Collections)的BiMap。
BiMap 是一个允许用户从两个方向执行查找的地图。 BiMap 中的键和值都是唯一的。
主要实现是HashBiMap。
inverse()
BiMap.inverse() 返回一个键类型和值类型位置交换的视图。
MutableBiMap<Integer, String> biMap =
HashBiMap.newWithKeysValues(1, "1", 2, "2", 3, "3");
MutableBiMap<String, Integer> inverse = biMap.inverse();
Assert.assertEquals("1", biMap.get(1));
Assert.assertEquals(1, inverse.get("1"));
Assert.assertTrue(inverse.containsKey("3"));
Assert.assertEquals(2, inverse.put("2", 4));
put()
MutableBiMap.put() 在常规映射上的行为类似于 Map.put(),但添加重复值时会抛出异常。
MutableBiMap<Integer, String> biMap = HashBiMap.newMap();
biMap.put(1, "1"); // behaves like a regular put()
biMap.put(1, "1"); // no effect
biMap.put(2, "1"); // throws IllegalArgumentException
forcePut()
这类似于MutableBiMap.put(),但它会在将键值对放入映射之前静默删除具有相同值的映射条目。
MutableBiMap<Integer, String> biMap = HashBiMap.newMap();
biMap.forcePut(1, "1"); // behaves like a regular put()
biMap.forcePut(1, "1"); // no effect
biMap.put(1, "2"); // replaces the [1,"1"] pair with [1, "2"]
biMap.forcePut(2, "2"); // removes the [1, "2"] pair before putting
Assert.assertFalse(biMap.containsKey(1));
Assert.assertEquals(HashBiMap.newWithKeysValues(2, "2"), biMap);
注意:我是 Eclipse Collections 的提交者。
【讨论】:
接受的答案提到了BiMap,但它在 Google Guava 库中变成了more up-to-date。
BiMap<K, V>是Map<K, V>
- 允许您查看“逆”
BiMap<V, K>和inverse()- 确保值是唯一的,使
values()成为Set
所以,你可以得到这样的代码:
final BiMap<String, Integer> biMap = HashBiMap.create();
biMap.put("word", 1);
biMap.put("alpha", 2);
System.out.println(biMap.get("word")); // prints 1
System.out.println(biMap.inverse().get(1)); // prints word
此对象的一些注意事项:
IllegalArgumentException。你可以使用forcePut(key, value),但那将是override the existing key-value pair。【讨论】: