views:

388

answers:

1

Before using google collections I had something similar to next code:

private Set<A> aSet = ...;
private Set<B> bSet = ...;

public Foo getFoo (Map<?, List<Bar>> bars, Set<?> set) {
   for (Object item : set) {
      for (Bar bar : bars.get (item)) {
          //build foo;
      }
   }
   ...
}

and I was able to make calls like these:

Map<A, List<Bar> aMap = getAMap ();
Foo f1 = getFoo (aMap, aSet);
Map<B, List<Bar> bMap = getBMap ();
Foo f2 = getFoo (bMap, bSet);

Now, with Multimap, I cannot do the same:

public Foo getFoo (Multimap<?, List<Bar>> bars, Set<?> set) {
   for (Object item : set) {

      // compile error: get(capture#621 of ?) in Multimap ... cannot be applied to java.lang.Object
      for (Bar bar : bars.get (item)) {
          //build foo;
      }
   }
   ...
}
+7  A: 

Try this:

public <T> Foo getFoo (Multimap<T, List<Bar>> bars, Set<T> set) {
   for (T item : aSet) {

      // compile error: get(capture#621 of ?) in Multimap ... cannot be applied to java.lang.Object
      for (Bar bar : bars.get (item)) {
         //build foo;
      }
   }
   ...
}

EDIT:

If you see the javadoc for both classes, you will realize that the javadoc for Map is:

V get(Object key) 

and for MultiMap is:

Collection<V> get(K key) 

See that the parameter for Map is not generified.

The MultiMap is better for generic, but Map is designed so it has backward compability with previous Map from Java 1.4.

nanda
Yes, it works. But I don't clearly understand why do we need to specify <T>?
Roman
T makes sure that the element of set and key of the map is from the same type
nanda
Multimap has to be certain the key is of the correct type, because the collection you get back is "write-through" into the multimap itself. (i.e., you can add an element to it, and the corresponding entry appears in the multimap; if the key had been of the wrong type, we'd have corrupted the data). Map has no such concern, and is absolutely correct in using Object as the parameter type to get().
Kevin Bourrillion