Arpssss Arpssss - 4 months ago 17
Java Question

Issue with Guava's BiMap and LinkedHashMap

Is it possible in Guava,


  1. To conduct a reverse lookup in BiMap for key and multiple values? Precisely, I have key and corresponding multiple values, I want to get key from a value.

  2. To store multiple values in LinkedHashMap? Precisely, I want to store, key - multiple values in some order thus I can get key position in the list.


Answer

Ad. 1. I suppose you want BiMap reverse lookup (BitMap does not exist in Guava)? Yes, it's possible, you just call inverse on your BiMap<K, V> and you get inversed BiMap<V, K> view of your bimap.

Example (taken from Guava's test suite):

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"));
}

Ad. 2. Assuming you mean "I want to store, key -> multiple [collection] values" (Map<K, Collection<V>>), ListMultimap is probably what you want, more precisly ArrayListMultimap (preserves values order) or LinkedListMultimap (preserves both keys and values order). If your object is going to be immutable, I strongly advice you use ImmutableListMultimap.

You can also create your own implementation of Multimap by using factory (bit verbose), i.e. I use:

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
}

P.S. Take a look at Guava's wiki, which is explaining both BiMap and Multimaps.

Comments