2010-02-20 9 views
11

Secondo HashSet javadoc, HashSet.contains restituisce solo un valore booleano. Come posso "trovare" un oggetto in un hashSet e modificarlo (non è un tipo di dati primitivo)?come trovare e restituire oggetti in java hashset

Vedo che HashTable ha un metodo get(), ma preferirei usare il set.

+0

grazie tutti! Il mio oggetto contiene in realtà un elenco collegato che ho bisogno di aggiornare frequentemente, quindi penso che andrò semplicemente con HashTable piuttosto che fare un'iterazione costosa per ogni aggiornamento degli oggetti. – user276712

risposta

11

È possibile rimuovere un elemento e aggiungerne uno diverso.

La modifica di un oggetto mentre è in un set di hash è una ricetta per il disastro (se la modifica modifica il valore di hash o il comportamento di uguaglianza).

+1

Questo non è completamente vero. È possibile modificare un elemento HashSet in modo sicuro se la modifica non influisce sull'uguaglianza dell'oggetto (e sul codice hash). Ad esempio, se equals e hashCode non sono stati sovrascritti, la modifica è sicura perché l'uguaglianza non viene modificata. –

+2

Sì, ed è per questo che ho scritto la parte tra parentesi. – starblue

2

È possibile scorrere il set per trovare l'oggetto.

Una parola di avvertimento dal API doc però:

"Nota: Grande prudenza è d'obbligo se oggetti mutabili vengono utilizzati come elementi di impostare il comportamento di un insieme non è specificato se il valore di un oggetto è. modificato in un modo che influisce su confronti uguali mentre l'oggetto è un elemento dell'insieme. "

+2

"You iterate ..." ma ovviamente se lo fai, aggiornare un elemento set diventa un'operazione 'O (N)'. –

12

Per citare la fonte del titolo Sun java.util.HashSet:

public class HashSet<E> 
    extends AbstractSet<E> 
    implements Set<E>, Cloneable, java.io.Serializable 
{ 
    static final long serialVersionUID = -5024744406713321676L; 

    private transient HashMap<E,Object> map; 

Così si stanno pagando per una mappa, si potrebbe anche usarlo.

+3

Penso che tu stia cercando di dire "usa una HashMap" ... corretto? :-) –

+5

Sì. Scusa, a volte non riesco a resistere all'impulso di risolvere piccoli enigmi con le risposte. – bmargulies

0
Object oldobj; //object to modify 
if (hashset.remove(oldobj)) { 
    Object newobj; //modified object 
    hashset.add(newobj); 
} 
0

Qualcosa di simile:

MyObject obj = new MyObject(); 
HashSet hashSet = new HashSet(); 
hashSet.add(obj); 

if (hashSet.contains(obj) == true) { 
    hashSet.remove(obj); 
    obj.setSomething(); 
    hashSet.add(obj); 
} 
+3

1. '== true' - non è necessario 2. non è stato selezionato il valore restituito di' .remove (obj) ' 3.' .contains() 'non è necessario se si rimuove al passaggio successivo –

+1

Despide il fatto che tutto è vero, non dovresti essere così schizzinoso :) – kovica

-1

ho incontrato lo stesso problema e si avvicinò con la seguente soluzione (dovrebbe implementare l'interfaccia Set, ma non tutti i metodi sono qui)

public class MySet<T> implements Set<T>{ 

    private HashMap<T,T> items = new HashMap<T,T>(); 


    public boolean contains(Object item) 
    { 
     return items.containsKey(item); 
    } 

    public boolean add(T item) 
    { 
     if (items.containsKey(item)) 
      return false; 
     else 
     { 
      items.put(item, item); 
      return true; 
     } 
    } 

    public T get(T item) 
    { 
     return items.get(item); 
    } 
} 
+1

Non è necessario delegare. Semplicemente usa HashMap invece di HashSet. – mostruash

Problemi correlati