2012-09-03 27 views
31

¿Cómo podemos eliminar duplicados de la lista con la ayuda de Guava api?Eliminar duplicados de la lista usando Guava

Actualmente estoy siguiendo esto:

private List<T> removeDuplicate(List<T> list){ 
return new ArrayList<T>(new LinkedHashSet<T>(list)); 
} 
+5

por qué te gusta ir de guayaba, si conjunto básico hace esto? –

+0

y de una manera tan concisa, también – Thilo

+0

@PriyankDoshi ¿por qué no simplemente 'HashSet'? – oldrinb

Respuesta

63

Probablemente la forma más eficiente es ImmutableSet.copyOf(list).asList(), que elimina los duplicados y conserva el orden de las iteraciones.

(Sin embargo, su aplicación con LinkedHashSet sería tan eficiente, y no habría vomitar en los nulos, en el improbable caso de que realmente quería nulos en su colección.)

+3

_Si_ no tiene elementos nulos;) – Xaerxess

+1

Es cierto, pero el 95% de las colecciones no. –

0

Usted puede tratar de multijuego API de guayaba para eliminar duplicates.Just añadir su lista de hacer el conjunto y utilizar el método de recuento.

MultiSet

1

Si quieres utilizar guayaba a cualquier precio que puede hacer

return new ArrayList<T>(HashMultiSet<T>.create(list).elementSet()) 
1

Realmente no recomiendo el uso de (Linked)HashMultiSet hacer tareas que normalmente se realiza con ArrayList y (Linked)HashSet como se mencionó anteriormente OP - es menos legible para el programador Java regular y (probablemente) menos eficiente.

En su lugar, al menos usar constructores de fábrica estáticas como newArrayList y newLinkedHashSet para evitar todos estos <T> s:

private static <T> List<T> removeDuplicate(final List<T> list) { 
    return Lists.newArrayList(Sets.newLinkedHashSet(list)); 
} 

Sin embargo, puede hacerlo en más "camino de guayaba" - por avoiding nulls y el uso de immutable collections.

Así que si su colección no puede tiene elementos nulos, me gustaría sugerir el uso de immutable set en lugar de mutable and less efficient one:

private static <T> List<T> removeDuplicate(final List<T> list) { 
    return Lists.newArrayList(ImmutableSet.copyOf(list)); 
} 

Todavía es copiar objetos en dos ocasiones, por lo que consideran ser completamente inmutable y el cambio de método de firma de retorno ImmutableList:

private static <T> ImmutableList<T> removeDuplicate(final List<T> list) { 
    return ImmutableSet.copyOf(list).asList(); 
} 

De esta manera sólo hay una copia involucrados, porque ImmutableCollection.asList() devuelve una vista.

12

Me encanta Louis' answer para la simplicidad de la misma (y porque es la única respuesta que no requiere 2 iteraciones completas), pero desafortunadamente en el mundo real, a menudo se encuentran situaciones en las que ocurre null. Aquí hay una versión ligeramente más largo nula de fallos:

ImmutableSet.copyOf(
    Iterables.filter(
     list, Predicates.not(Predicates.isNull()))).asList(); 

O, con las importaciones estáticas:

copyOf(filter(list, not(isNull()))).asList(); 

Por supuesto que tienen que ser conscientes del hecho de que todos los null valores se perderán de la lista.

+3

Hay un predicado 'Predicates.notNull()' ya disponible. Entonces, el resultado final sería 'copyOf (filter (list, notNull())). AsList();'. – Jonas

+0

@Jonas cierto. pero en el momento en que escribí esto, el método no existía –

7

con predicado genérico

class DuplicateRemover<T> implements Predicate<T> { 

    private final Set<T> set = new HashSet<>(); 

    @Override 
    public boolean apply(T input) { 

     boolean flag = set.contains(input); 

     if (!flag) { 
      set.add(input); 
     } 

     return !flag; 
    } 

} 
+1

Tenga en cuenta que set.add devuelve verdadero solo si el elemento realmente se agregó, por lo que la llamada a set.contains es innecesaria. – Trejkaz

Cuestiones relacionadas