2011-06-04 15 views
17

¿Existe un método integrado o combinación de métodos para devolver una vista filtrada de Guava ImmutableMultimaps utilizando predicados, como se puede hacer con los mapas regulares?Filtrado Guava Multimaps

No parece haber un método Maps.filter que acepte un ImmutableMultimap como parámetro. Al mirar la API, podría llamar a AsMap() y obtener una vista basada en el mapa de la multimapa y realizar el filtro de esa manera. Sin embargo, necesito devolver ImmutableMultimap desde mi función y, por razones obvias, no hay forma de ver un Mapa> como un ImmutableMultimap, sin tener que construir un nuevo Multimap.

Incluso si pudiera filtrarlo como un mapa y devolverlo a un ImmutableMultimap ya que todas son solo vistas (¿no?), Los métodos de filtro solo me permitirían filtrar en la colección como un todo sin eliminar los valores individuales .

+0

¿Está buscando para filtrar las teclas o los valores? –

+0

Debo filtrar ambos. En una instancia, solo en las teclas, en la otra, una clave y un valor. – broconne

+0

Consulte http://stackoverflow.com/questions/6176918/google-collections-guava-libraries-immutableset-list-map-and-filtering para obtener algunas ideas. – Istao

Respuesta

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

¿Hay un método integrado ...

+0

Gracias por el fragmento de código. Eso es esencialmente lo que terminé haciendo, pero usé el constructor ImmutableMultiMap para no tener que crear un mapa y luego volver a crearlo como un mapa inmutable. – broconne

0

Sobre la reflexión, no creo que hay una manera de crear una vista filtrada de un ImmutableMultimap de una muy buena razón Si un objeto espera una ImmutableMultiMap, esperaría que ese objeto no parezca cambiar durante el tiempo de vida del objeto. La aplicación de un filtro, que podría funcionar dinámicamente, rompería ese contrato implícito (o posible, escrito por lo que sé) ya que, al parecer, entre las llamadas a varios métodos, el mapa de hecho había mutado.

4

En lugar de copiar el multimapa inmutable completo, puede intentar usar un ForwardingMultimap y aplicar el filtro cuando se consulta el mapa, p.

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

y así sucesivamente.