2010-02-10 12 views
33

Ho letto i dati da un file di testo, quindi ci può essere:Salvare una lista di stringhe uniche al ArrayList

 
John 
Mary 
John 
Leeds 

ora ho bisogno di ottenere 3 elementi unici nel ArrayList, perché ci sono solo 3 unici valori nell'output del file (come sopra).

Posso usare una HashTable e aggiungervi informazioni, quindi copiare semplicemente i suoi dati nella lista. Ci sono altre soluzioni?

risposta

73

Perché è necessario memorizzarlo in un List? In effetti, è necessario ordinare i dati o supportare ricerche basate su indici?

Suggerirei di memorizzare i dati in un Set. Se l'ordine non è importante, è necessario utilizzare HashSet. Tuttavia, se si desidera conservare l'ordine, è possibile utilizzare LinkedHashSet.

+1

Perché? Cause Gli elenchi vengono utilizzati più spesso e sono facili da utilizzare. Penso che se scrivi codice per altri sviluppatori è meglio restituire un tipo di Elenco rispetto a qualsiasi altro tipo. – EugeneP

+0

Non necessariamente. L'unico caso in cui avresti bisogno di una lista è se vuoi un accesso casuale indicizzato agli elementi nelle raccolte. Altrimenti sarebbe preferibile utilizzare semplicemente HashSet o LinkedHashSet. –

+0

Secondo me il codice è più pulito quando si utilizza l'indice. Hai il controllo su "dove ti trovi" all'interno della struttura dati. Potrebbe venire dalla mia esperienza con il linguaggio C. – EugeneP

16

È possibile controllare list.contains() prima di aggiungere.

if(!list.contains(value)) { 
    list.add(value); 
} 

Ho immaginato che sarebbe stato ovvio! Tuttavia, aggiungere elementi a un hashset e quindi creare un elenco da questo set sarebbe più efficiente.

+0

Suppongo che usi il metodo "uguale"? – EugeneP

+0

Sì, usa equals() sulla stringa internamente. –

+0

Sì. Grazie. Nel mio caso sarebbe preferibile, perché il codice verrà tenuto pulito. Ma suppongo che l'algoritmo di HashTable sia più veloce del metodo contains, a meno che non utilizzi internamente una HashTable. – EugeneP

61

Se si dispone di un List contenenti i duplicati, e si desidera un List a meno, si potrebbe fare:

List<String> newList = new ArrayList<String>(new HashSet<String>(oldList)); 

Cioè, avvolgere il vecchio elenco in un insieme per rimuovere i duplicati e avvolgere quel set in una lista di nuovo.

+0

Suppongo, non vi è alcuna garanzia che l'ordinamento di 'newList' sarà uguale a quello di' oldList', o? – Marvin

+7

O.k. Ho trovato la risposta al mio commento: Se usi 'LinkedHashSet' invece di' HashSet', conservi l'ordine. – Marvin

1

Ecco come ho risolto:

import groovy.io.*; 
def arr = ["5", "5", "7", "6", "7", "8", "0"] 
List<String> uniqueList = new ArrayList<String>(new HashSet<String>(arr.asList())); 
System.out.println(uniqueList) 
0
class HashSetList<T extends Object> 
    extends ArrayList<T> { 

    private HashSet<Integer> _this = new HashSet<>(); 

    @Override 
    public boolean add(T obj) { 
     if (_this.add(obj.hashCode())) { 
      super.add(obj); 
      return true; 
     } 
     return false; 
    } 
} 

io uso quelli tipo di struttura per i piccoli programmi, voglio dire di avere un overhead minimo per avere getter e setter, ma l'unicità. Inoltre, puoi decidere di sostituire hashCode per decidere se il tuo articolo è uguale a un altro.

+0

Bella idea, ma ... che dire rimuovere e aggiungere (int, *) etc? Questa soluzione non è completa. –

Problemi correlati