2012-09-03 2 views
31

Come rimuovere i duplicati dall'elenco con l'aiuto di Guava api?Rimuovere i duplicati dall'elenco utilizzando Guava

Attualmente sto seguendo questo:

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

perché ti piace andare per guava, se insieme di base fa questo? –

+0

e in modo così sintetico, anche – Thilo

+0

@PriyankDoshi perché non solo 'HashSet'? – oldrinb

risposta

63

Probabilmente il modo più efficace è ImmutableSet.copyOf(list).asList(), che elimina i duplicati e mantiene l'ordine di iterazione.

(Ma l'implementazione con LinkedHashSet sarebbe quasi altrettanto efficace, e non getterebbe su valori nulli, nel caso improbabile che in realtà voleva null nella vostra collezione.)

+3

_If_ non hai elementi null;) – Xaerxess

+1

Vero, ma il 95% delle raccolte no. –

0

Si può cercare di Guava MultiSet API per rimuovere duplicates.Just aggiungere l'elenco fare il set e utilizzare il metodo di conteggio.

MultiSet

1

Se volete utilizzare Guava a qualsiasi prezzo che si può fare

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

davvero consiglia di non utilizzare (Linked)HashMultiSet fare compito che di solito è fatto con ArrayList e (Linked)HashSet come OP di cui sopra - È meno leggibile per i normali programmatori Java e (probabilmente) meno efficiente.

Invece, almeno usare costruttori di fabbrica statici come newArrayList e newLinkedHashSet per evitare tutti questi <T> s:

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

Tuttavia, si può fare in più "modo Guava" - da avoiding nulls e utilizzando immutable collections.

Quindi, se la vostra collezione non può avere elementi nulli, suggerirei usando immutable set invece di mutable and less efficient one:

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

E 'ancora la copia di oggetti per due volte, in modo da prendere in considerazione essendo completamente immutabile e cambiando il metodo di firma per il ritorno ImmutableList:

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

In questo modo v'è una sola copia coinvolti, perché ImmutableCollection.asList() restituisce la vista.

12

amo Louis' answer per la semplicità di esso (e perché è l'unica risposta che non richiede 2 iterazioni complete), ma sfortunatamente nel mondo reale, spesso si verificano situazioni in cui si verifica null. Ecco una versione leggermente più lunga null-sicuro:

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

Oppure, con le importazioni statiche:

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

Naturalmente è necessario essere consapevoli del fatto che tutti i null valori verranno persi dalla lista.

+3

Esiste già un predicato 'Predicates.notNull()'. Quindi il risultato finale sarebbe 'copyOf (filter (list, notNull())). AsList();'. – Jonas

+0

@Jonas true. ma al momento in cui scrissi questo metodo non esisteva –

7

con predicato generico

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

Nota che set.add restituisce true solo se l'elemento è stato effettivamente aggiunto, quindi la chiamata a set.contains non è necessaria. – Trejkaz