开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜