2012-05-31 9 views
17

Me gustaría saber en Guava si hay alguna diferencia entre los métodos Iterables.filter(Iterable, Predicate) y Collections2.filter(Collection, Predicate)?Guava: Iterables.filter VS Collections2.filter, ¿alguna gran diferencia?

Parece que ambos mantienen el orden de iteración y proporcionan una vista en vivo. Javadoc dice que al llamar al Collections2.filter().size() se iterará sobre todos los elementos.

Supongamos que tengo un predicado para filtrar una lista de elementos, y como resultado quiero el número de elementos que quedan en la vista (o la lista, no importa). ¿Qué se supone que debo usar? Parece más simple usar Collections2.filter ya que el método size() es proporcionado por Collection s.

Pero en el fondo, hay una diferencia entre:

ImmutableList.copyOf(
    Iterables.filter(lead.getActions(), isRealActionDoneByUserPredicate) 
).size(); 

Y:

Collections2.filter(lead.getActions(),isRealActionDoneByUserPredicate).size(); 

Por cierto, está construyendo una ImmutableList más rápido que la construcción de una normal de ArrayList?

+0

Simplemente indicando lo obvio: uno te da 'Iterable' y el otro te da' Collection'. Debajo de 'Collections2.filter' utiliza' FilteredCollection' [link] (https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/collect/Collections2.java# 133) que delega muchas cosas a 'Iterables' /' Iterators' por lo que no debería haber diferencias funcionales. Por ejemplo, 'FilteredCollection # size()' es exactamente 'Iterators.size (Iterators.filter (unfiltered.iterator(), predicate))' como lo indica la respuesta de @Louis Wasserman. –

Respuesta

22

Contribuyente de guayaba aquí.

Collections2.filter(elements, predicate).size() 

es preferible, ya que no hace la copia - ambos filter métodos devuelven una vista - pero

Iterables.size(Iterables.filter(elements, predicate)) 

es esencialmente equivalente, y de manera similar se encuentra la respuesta sin ninguna copia.

En cuanto a la velocidad relativa de la construcción de un ArrayList frente a un ImmutableList, que varía según el método de construcción que utilice:

  • ImmutableList.copyOf(collection) debe tener casi exactamente la misma cantidad de tiempo. (Tiene que verificar nulos, pero eso es barato.)
  • ImmutableList.builder()....build() toma un pequeño factor constante más tiempo, porque tiene que usar un ArrayList dentro del Builder, ya que no sabemos de antemano cuántos elementos se agregarán.
  • ImmutableList.of(...) tendrá aproximadamente la misma velocidad.

Dicho esto, el conceptuales beneficios del uso de ImmutableList menudo pesan más que los pequeños gastos de funcionamiento, especialmente si va a estar pasando las listas con frecuencia.

+0

Gracias. Creo que te refieres a Iterables.size() No encuentro ningún Iterables.length() –

+0

Sí, es malo. Fijo. –

+0

Tangencial, pero ¿han pensado ustedes en dar al constructor 'Builder'sa que tome' int expectedSize' (y exponer los métodos correspondientes 'builder (int)'? ¿O habría muy poco beneficio para el ruido agregado en la API? –

Cuestiones relacionadas