Guava 的 BiMap 和 LinkedHashMap 的问题
-
12-12-2019 - |
题
番石榴有可能吗,
进行反向查找
BiMap
对于键和多个值?准确地说,我有键和对应的多个值,我想从值中获取键。存储多个值
LinkedHashMap
?准确地说,我想按某种顺序存储键多个值,这样我就可以获取列表中的关键位置。
解决方案
广告。1. 是的,可以使用以下命令进行反向查找 BiMap<K, V>
, ,你只需调用 inverse
在你的 BiMap
你就会变得相反 BiMap<V, K>
看法 你的 BiMap
.
示例(取自 Guava 的测试套件):
public void testMapConstructor() {
/* Test with non-empty Map. */
Map<String, String> map = ImmutableMap.of(
"canada", "dollar",
"chile", "peso",
"switzerland", "franc");
HashBiMap<String, String> bimap = HashBiMap.create(map);
assertEquals("dollar", bimap.get("canada"));
assertEquals("canada", bimap.inverse().get("dollar"));
}
广告。2. 假设你的意思是 “我想存储键 -> 多个[集合]值” (Map<K, Collection<V>>
), ListMultimap
可能是你想要的,更准确地说 ArrayListMultimap
(保留值顺序)或 LinkedListMultimap
(保留键和值的顺序)。如果你的对象是不可变的,我强烈建议你使用 ImmutableListMultimap
.
您还可以创建自己的实现 Multimap
通过使用 工厂 (有点冗长),即我用:
private static <K, V> ListMultimap<K, V> makeLinkedArrayListMultimap() {
return Multimaps.newListMultimap(Maps.<K, Collection<V>>newLinkedHashMap(),
new Supplier<List<V>>() {
@Override public List<V> get() {
return Lists.newArrayList();
}
});
}
public static void main(final String[] args) {
final ListMultimap<String, String> multimap = makeLinkedArrayListMultimap();
multimap.putAll("one", ImmutableList.of("zero", "three"));
multimap.putAll("two", ImmutableList.of("three", "four", "three"));
multimap.putAll("three", ImmutableList.<String>of()); // note that this doesn't add key to multimap
multimap.put("four", "forty-two");
System.out.println(multimap);
// prints {one=[one, three], two=[three, four, three], four=[forty-two]}
final List<String> listForOnes = multimap.get("one");
System.out.println(listForOnes.get(0));
// prints zero
}
附: 看一眼 番石榴的维基, ,这解释了两者 BiMap
和 Multimap
.
其他提示
在guava中最接近 Multiset
将多个值映射到键,但我怀疑它满足您的要求。
- 我怀疑使用值查找密钥是好主意(当您有多个值映射到单个键时),为了执行此操作,您的值应该是唯一的,并且考虑您的数据结构(这就像世代odicetagcode)无法保证有独特的价值。
- guava的另一个选项是
Map<Key, Collection<Value>
,它需要唯一的值,可以提供反向映射(值 - >键),但由于您需要将多个值映射到相同的键,这也不适合。
作为 @Xaerxess 说在 他的回答 对于你的第二个问题,你可以自己做 ListMultimap
使用一个 LinkedHashMap
作为其支持地图使用 Multimaps.newListMultimap
方法。
对于你的第一个问题,你有映射到多个值的键(即A Multimap
),你可以使用该方法 Multimaps.invertFrom
创建原件的倒置副本 Multimap
进行反向查找。此外,您还可以创建一个 ImmutableListMultimap
原件的副本并使用其 inverse()
方法来获得逆,尽管这只是复制原始的,就像 Multimaps.invertFrom
确实如此(尽管它会缓存它,所以重复调用 inverse()
返回相同的副本。)
如果您不介意额外的内存消耗,想要进行多次反向查找,并且不需要反向副本来跟上创建后发生的原始更改的最新情况,那么这可能是值得的。如果您只想查找映射到一个特定值的键,则可以在条目的一次迭代中完成此操作,而无需创建完整副本。