Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering Guava Multimaps

Tags:

java

guava

Is there a a built-in method or combination of methods to return a filtered view of Guava ImmutableMultimaps using predicates, like you can with regular maps?

There does not appear to be Maps.filter method that accepts an ImmutableMultimap as a parameter. Looking at the API I could call asMap() and get a map based view of the multimap and perform the filter that way. However, I need to return an ImmutableMultimap from my function and for obvious reasons there isn't a way to view a Map> as an ImmutableMultimap - without having to contruct a new Multimap.

Even if I could filter it as a Map and cast it back to an ImmutableMultimap since they are all just views (I think?), the filter methods would only let me filter on the collection as a whole not removing individual values.

like image 338
broconne Avatar asked Jun 04 '11 00:06

broconne


3 Answers

Multimaps.filterEntries was added to Guava in release 11.

like image 70
Louis Wasserman Avatar answered Oct 13 '22 00:10

Louis Wasserman


Instead of copying the complete immutable multimap, you coud try to use a ForwardingMultimap and apply the filter when the map is queried, e.g.

@Override
public boolean containsKey(@Nullable Object key) {
  if (!keyFilter.apply(key))
    return false;
  return super.containsKey(key);
}

@Override
public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
  ..
}

@Override
public Collection<V> get(@Nullable K key) {
  if (!keyFilter.apply(key))
    return Collections.emptyList();
  return Collections2.filter(delegate().get(key), valueFilter);
}

and so on.

like image 20
Sebastian Zarnekow Avatar answered Oct 12 '22 22:10

Sebastian Zarnekow


public static <Type1, Type2> ImmutableMultimap<Type1, Type2> dFilter(
        ImmutableMultimap<Type1, Type2> data,//
        Predicate<Type1> predicate//
) {
    Multimap<Type1, Type2> result = HashMultimap.create();
    for (Type1 t1 : data.keys())
        if (predicate.apply(t1))
            for (Type2 t2 : data.get(t1))
                result.put(t1, t2);

    return ImmutableMultimap.copyOf(result);
}

Is there a built-in method ...

No.

like image 21
Margus Avatar answered Oct 12 '22 22:10

Margus