2

有没有可能在番石榴,

  1. BiMap对键和多个值进行反向查找?准确地说,我有键和对应的多个值,我想从一个值中获取键。

  2. 将多个值存储在LinkedHashMap? 准确地说,我想以某种顺序存储键 - 多个值,因此我可以获得列表中的键位置。

4

3 回答 3

8

广告。1.是的,可以使用 a 进行反向查找,您只需BiMap<K, V>调用inverse您的.BiMapBiMap<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
}

PS看看Guava 的 wiki,它解释了BiMapMultimap

于 2012-03-12T10:01:48.560 回答
3

Guava 中最接近的是Multiset将多个值映射到键,但我怀疑它是否满足您的要求。

  1. 我怀疑使用值查找键是个好主意(当您有多个值映射到单个键时),为了做到这一点,您的值应该是唯一的,并且考虑到您的数据结构(例如Map<Key, Collection<Value>)它不能保证有独特的价值观。
  2. guava 的另一个选项是BiMap需要唯一值并且可以提供反向映射(值 -> 键),但是由于您需要将多个值映射到同一个键,所以这也不适合。
于 2012-03-12T09:53:38.560 回答
3

正如@Xaerxess对您的第二个问题的回答中所说,您可以使用该方法制作自己的ListMultimap使用 aLinkedHashMap作为其支持地图的地图Multimaps.newListMultimap

对于您的第一个问题,您将键映射到多个值(即 a Multimap),您可以使用该方法Multimaps.invertFrom创建原始副本的反向副本Multimap以进行反向查找。此外,您可以创建ImmutableListMultimap原件的副本并使用其inverse()方法来获取逆向,尽管这只是像复制原件一样Multimaps.invertFrom(尽管它会缓存它,因此重复调用以inverse()返回相同的副本。)

如果您不介意额外的内存消耗,想要进行多次逆向查找,并且不需要逆向副本来跟上您创建后发生的对原始内容的更改,这可能是值得的. 如果您只想查找映射到一个特定值的键,您可以在条目的一次迭代中执行此操作,而无需创建完整副本。

于 2012-03-12T17:59:13.860 回答