2

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.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Arpssss
  • 3,850
  • 6
  • 36
  • 80
  • Actually I want to solve this http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference issue. That's why, I think to replace all "foo" with single "foo" and then reverse look-up (for Key-Multiple Value Map) or get key from position which will save space(for Key-Multiple Value Map).However, it seems, I have to wast much space than I previously wast. Is there any Guava Solution of this http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference. Thanks. – Arpssss Mar 12 '12 at 20:11
  • 1
    This strongly feels like premature optimization you're trying to do. – Louis Wasserman Mar 13 '12 at 03:04

3 Answers3

8

Ad. 1. Yes, it's possible to do a reverse lookup with a BiMap<K, V>, you just call inverse on your BiMap 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 Multimap.

Grzegorz Rożniecki
  • 27,415
  • 11
  • 90
  • 112
  • Thanks. Actually I want to solve this http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference issue. That's why, I think to replace all "foo" with single "foo" and then perform reverse look-up (for Key-Multiple Value Map) or get key from position which will save space (for Key-Multiple Value Map).However, it seems from your Ans, I have to wast much space than I previously wast. Is there any Guava Solution of http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference. Thanks. – Arpssss Mar 12 '12 at 20:08
3

The closest in Guava is Multiset to map multiple values to key, but I doubt it satisfies your requirement.

  1. I doubt it is good idea to look up key using values (when you have multiple values mapped to single key), in order to do this your value should be unique and considering your data structure (which is like Map<Key, Collection<Value>) it cannot be guaranteed to have unique values.
  2. The another option with guava is BiMap which requires unique values and can provide a reverse mappings (value -> key) but since you need to map multiple values to same key, this also not a good fit.
Grzegorz Rożniecki
  • 27,415
  • 11
  • 90
  • 112
Premraj
  • 7,802
  • 8
  • 45
  • 66
3

As @Xaerxess says in his answer to your 2nd question, you can make your own ListMultimap that uses a LinkedHashMap as its backing map using the Multimaps.newListMultimap method.

For your 1st question, where you have keys mapped to multiple values (i.e. a Multimap), you can use the method Multimaps.invertFrom to create an inverted copy of your original Multimap to do inverse lookups on. Also, you can create an ImmutableListMultimap copy of the original and use its inverse() method to get the inverse, though that's just going to copy the original just like Multimaps.invertFrom does (though it will cache it so repeated calls to inverse() return the same copy.)

This is likely worth it if you don't mind the extra memory consumption, are going to want to do multiple inverse lookups, and don't need the inverse copy to stay up to date with changes to the original that happen after you create it. If you just want to lookup the keys that map to one specific value, you can do that in one iteration of the entries without creating a full copy.

Neuron
  • 5,141
  • 5
  • 38
  • 59
ColinD
  • 108,630
  • 30
  • 201
  • 202
  • I agree, `Multimaps.invertFrom` and `ImmutableXXXMultimap.invert()` are very useful. @OP - see my [answer to another question with example code for `ImmultableListMultimap.invert()`](http://stackoverflow.com/a/8439744/708434). – Grzegorz Rożniecki Mar 12 '12 at 18:19
  • @ColinD, Thanks.Actually I want to solve this http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference issue. That's why, I think to replace all "foo" with single "foo" and then reverse look-up (for Key-Multiple Value Map) or get key from position which will save space(for Key-Multiple Value Map).However, it seems from your Ans, I have to wast much space than I previously wast. Is there any Guava Solution of http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference. Thanks. – Arpssss Mar 12 '12 at 20:05
  • @Arpssss: I'm afraid that it's really unclear to me both in this question and that one what you actually want to do, so I'm not sure I can help you. In the other question, it sounds to me like you're worrying about something you _probably_ shouldn't be worrying about, but again I can't really say without any details. – ColinD Mar 12 '12 at 20:50