2010-02-20 25 views
11

Zgodnie z javascript HashSet, HashSet.contains zwraca tylko wartość boolowską. Jak mogę "znaleźć" obiekt w haszyszu i zmodyfikować go (nie jest to prymitywny typ danych)?jak znaleźć i zwrócić obiekty w javas hashset

Widzę, że HashTable ma metodę get(), ale wolałbym użyć zestawu.

+0

dzięki każdy! Mój obiekt zawiera listę połączoną, którą muszę często aktualizować, więc myślę, że po prostu pójdę z HashTable, zamiast wykonać kosztowną iterację dla każdej aktualizacji obiektu. – user276712

Odpowiedz

11

Możesz usunąć element i dodać inny.

Modyfikowanie obiektu, gdy znajduje się on w zestawie skrótów, jest receptą na katastrofę (jeśli modyfikacja zmienia wartość skrótu lub zachowanie równości).

+1

To nie jest do końca prawdą. Można bezpiecznie zmodyfikować element HashSet, jeśli zmiana nie wpłynie na równość obiektu (i kod skrótu). Na przykład, jeśli równe i hashCode nie zostały nadpisane, to zmiana jest bezpieczna, ponieważ jej równość nie jest zmieniana. –

+2

Tak, i dlatego napisałem tę część w nawiasach. – starblue

2

Możesz iterować przez zestaw, aby znaleźć swój obiekt.

Słowo ostrzeżenia od API doc jednak:

„Uwaga: Wielka należy zachować ostrożność, jeśli Zmienne obiekty są wykorzystywane jako zestaw elementów Zachowanie zestawu nie jest określony, jeżeli wartość przedmiotu jest. zmienione w sposób, który wpływa na równe porównania, podczas gdy obiekt jest elementem w zestawie. "

+2

"Możesz iterować ...", ale oczywiście jeśli to zrobisz, aktualizacja zestawu elementów stanie się operacją 'O (N)'. –

12

Cytując źródła photography 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; 

Więc płacisz za mapy, równie dobrze można z niego korzystać.

+3

Myślę, że próbujesz powiedzieć "użyj mapy HashMap" ... poprawnie? :-) –

+5

Tak. Przepraszam, czasami nie mogę oprzeć się pokusie, by rozwiązywać małe zagadki. – bmargulies

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

Coś jak:

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' - jest niepotrzebne 2. nie sprawdziłeś wartości zwracanej' .remove (obj) ' 3.' .contains() 'nie jest konieczne, jeśli usuniesz w następnym kroku –

+1

Despide the fakt to wszystko prawda, nie powinieneś być tak wybredny :) – kovica

-1

I napotkał ten sam problem i wymyślił następujące rozwiązanie (powinien implementować interfejs ustawiona, ale nie wszystkie metody są tutaj)

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

Nie musisz delegować. Po prostu użyj HashMap zamiast HashSet. – mostruash