Filtering Guava Multimaps
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 开发者_StackOverflow中文版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.
Multimaps.filterEntries was added to Guava in release 11.
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.
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.
Upon reflection, I don't think there is a way to create a filtered view of an ImmutableMultimap for a very good reason. If an object expects an ImmutableMultiMap, it would expect that object to not appear to change for the lifetime of the object. Applying a filter, that could operate dynamically, would break that implied (or possible written for all I know) contract as it would appear that between calls to various methods the map had in fact mutated.
精彩评论