2009-05-13 9 views
17

Powiedzmy, że chcę umieścić słowa w strukturze danych i chcę mieć stałe sprawdzanie czasu, aby sprawdzić, czy dane słowo znajduje się w tej strukturze danych. Wszystko, co chcę zrobić, to sprawdzić, czy słowo istnieje. Czy użyłbym do tego funkcji HashMap (containsKey())? HashMap s używaj par kluczy-> wartości, ale w moim przypadku nie mam wartości. Oczywiście mógłbym użyć wartości null dla wartości, ale nawet wartość null zajmuje miejsce. Wygląda na to, że powinna istnieć lepsza struktura danych dla tej aplikacji.Java hashmaps bez wartości?

Kolekcja może potencjalnie być używana przez wiele wątków, ale ponieważ obiekty zawarte w kolekcji nie ulegną zmianie, nie sądzę, że mam wymagania synchronizacji/współbieżności.

Czy ktoś może mi pomóc?

Odpowiedz

41

Zamiast tego użyj HashSet. Jest to implementacja skrótu Set, która jest używana głównie do tego, co opisujesz (nieuporządkowany zestaw elementów).

+0

Gdybym użył czegoś takiego jak hashSet, czy to znaczy, że nie mogę używać ciągów? hashSet.add ("klucz"); hashSet.contains ("klucz"); // false, prawda? Ponieważ dwa klucze są oddzielnymi obiektami? – jbu

+0

nie, zwraca true. Hashset jest idealny. – jbu

+4

Powinieneś być w stanie używać Strings dobrze, ponieważ String ma własną implementację hashCode(), która zwraca ten sam skrót dla łańcuchów, które są równe. Odsyłacz: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#hashCode() –

6

Chcesz użyć kolekcji implementującej interfejs zestawu, prawdopodobnie HashSet, aby uzyskać wydajność, którą podałeś. Zobacz http://java.sun.com/javase/6/docs/api/java/util/Set.html

+0

Gdybym użył czegoś takiego jak hashSet, czy to znaczy, że nie mogę używać ciągów? hashSet.add ("klucz"); hashSet.contains ("klucz"); // false, prawda? Ponieważ dwa klucze są oddzielnymi obiektami? – jbu

+0

nie, zwraca true. Hashset jest idealny – jbu

+0

jbu, użyje pierwszego hashCode(), a następnie equals(), aby sprawdzić członkostwo (ten ostatni sprawdza kolizje). W przypadku obiektów ze standardowej biblioteki, takich jak String, jesteś w dobrej formie. Jeśli definiujesz własne obiekty, upewnij się, że hashCode() i equals() są poprawnie zdefiniowane. –

1

Inne niż Set s, w pewnych okolicznościach może chcesz przekonwertować Map do Set z Collections.newSetFromMap(Map<E,Boolean>) (niektóre Map s zabronić null wartości, stąd Boolean).

6

Prawdopodobnie chcesz użyć java.util.Set. Implementacje obejmują java.util.HashSet, który jest odpowiednikiem HashMap.

Nawet jeśli obiekty znajdujące się w kolekcji nie ulegną zmianie, może być konieczna synchronizacja. Czy nowe obiekty muszą zostać dodane do zbioru po przekazaniu zestawu do innego wątku? Jeśli tak, możesz użyć parametru Collections.synchronizedSet(), aby ustawić opcję Ochrona wątków.

Jeśli masz Mapę z wartościami i masz jakiś kod, który chce traktować Mapę jako Set, możesz użyć Map.entrySet() (pamiętaj jednak, że entrySet zwraca widok Set klawiszy na mapie, jeżeli mapa jest zmienna, Mapę można zmienić za pomocą zestawu zwróconego przez entrySet).

6

Generalnie używasz implementacji Zestaw, a najczęściej HashSet. Jeśli potrzebujesz równoczesnego dostępu, to ConcurrentHashSet zapewnia zastępczą wymianę, która zapewnia bezpieczny, równoczesny dostęp, w tym bezpieczną iterację po zestawie.

Polecam w każdym przypadku, mówiąc o nim jako po prostu Zestaw w całym kodzie, z wyjątkiem jednego miejsca, w którym go konstruujesz; w ten sposób łatwiej jest zrzucić jedną implementację dla drugiej, jeśli później tego zażądasz.

Nawet jeśli zestaw jest tylko do odczytu, jeśli jest używany przez wątek inny niż ten, który ją tworzy, to trzeba pomyśleć o bezpieczny publikacja (to znaczy, upewniając się, że każda inna wątek postrzega zestaw w spójnym stanie: pamiętaj, że jakiekolwiek zapisy w pamięci, nawet w konstruktorze, nie gwarantują, że będą dostępne dla innych wątków, kiedy lub w stanie, którego się spodziewasz, chyba że podejmiesz odpowiednie kroki, aby to zapewnić).Można to zrobić przez następujące:

  • upewniając się, że jedyne odniesienie do zestawu to final fields;
  • upewniając się, że rzeczywiście jest prawdą, że żaden wątek nie modyfikuje zestawu.

Możesz pomóc w zapewnieniu tego drugiego przy użyciu opakowania Collections.unmodifiableSet(). Daje ci to niemodyfikowalny widok danego zestawu - więc pod warunkiem, że nie ma innych "normalnych" odniesień do ustawionych ucieczek, jesteś bezpieczny.

-1

jak wszyscy mówili, że HashSet jest prawdopodobnie najprostszym rozwiązaniem, ale nie będziesz mieć stałego sprawdzania czasu w HashSet (ponieważ wpisy mogą być powiązane) i będziesz przechowywać obojętny obiekt (zawsze taki sam) dla każdego wpisu ...

Dla informacji here a list of data structures może znajdziesz taki, który lepiej pasuje do Twoich potrzeb.