2011-06-04 44 views
17

有没有一种内置方法或方法的组合来使用谓词返回Guava ImmutableMultimaps的过滤视图,就像您可以使用常规地图一样?过滤番石榴多图表

似乎没有接受ImmutableMultimap作为参数的Maps.filter方法。看看API,我可以调用asMap()并获取multimap的基于地图的视图,并以此方式执行过滤器。但是,我需要从我的函数返回一个ImmutableMultimap,因为显而易见的原因,没有办法将Map>视为ImmutableMultimap - 而无需构建新的Multimap。

即使我可以将它过滤为一个Map并将其转换回ImmutableMultimap,因为它们都只是视图(我认为?),过滤器方法只会让我过滤整个集合而不会删除单个值。

+0

您是否正在筛选键或值? – 2011-06-04 00:38:27

+0

我实际上需要对两者都进行过滤。在一个实例中只是在键上,另一个是键和值。 – broconne 2011-06-04 02:48:38

+0

请参阅http://stackoverflow.com/questions/6176918/google-collections-guava-libraries-immutableset-list-map-and-filtering以获取一些想法。 – Istao 2011-06-04 14:48:26

回答

1
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); 
} 

是否有一个内置的方法...

+0

感谢您的代码片段。这实际上就是我最终做的,但是我使用了ImmutableMultiMap构建器,所以我不必创建Map,然后将其重新创建为不可变映射。 – broconne 2011-06-06 13:17:12

0

通过反思,我不认为有一种方式来创建一个ImmutableMultimap的过滤视图一个非常好的理由。如果一个对象需要一个ImmutableMultiMap,它会希望该对象在该对象的生命周期中不会出现变化。应用一个可以动态操作的过滤器会打​​破这种隐含的(或者可能为我所知道的)合同,因为看起来在映射实际上已经变化的各种方法的调用之间。

4

而不是复制完整的不可变多图,你试图使用ForwardingMultimap并在查询地图时应用过滤器,例如,

@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); 
} 

等等。