2010-08-09 11 views
7

mam założyć HashMap tak:Jak mogę wyodrębnić ArrayList z HashMap i przepuścić przez nią w Javie?

Map<String, ArrayList<String>> theAccused = new HashMap<String, ArrayList<String>>(); 

... i wypełnić to, przechowując dla każdej nazwy (klawisz), wykaz nazwisk (wartości). Więc:

ArrayList<String> saAccused = new ArrayList<String>(); 
// populate 'saAccused' ArrayList 
... 
// done populating 
theAccused.put(sAccuser, saAccused); 

więc teraz chcę, aby przejrzeć wszystkie wpisy w HashMap i zobaczyć, czy (dla każdego „sAccuser”), lista „saAccused” zawiera pewną nazwę. To jest moja nieudana próba tak daleko:

Set<String> setAccusers = theAccused.keySet(); 
Iterator<String> iterAccusers = setAccusers.iterator(); 
iterAccusers.next(); 
ArrayList<String> saTheAccused; 

// check if 'sAccuser' has been accused by anyone before 
for (int i = 0; i < theAccused.size(); i++) { 
    saTheAccused = theAccused.get(iterAccusers); 

    if (saTheAccused.contains(sAccuser)) { 

    } 
    iterAccusers.next(); 
} 

... jednak nie jestem pewien, jak działa klasy Set i Iterator:/Problem polega na tym, że nie mają „wartości” na ... nazwy ... 'sAccuser' s ... dostępne HashMap.

W skrócie, chcę powtórzyć przez HashMap i sprawdzić, czy konkretna nazwa jest przechowywana na dowolnej liście. Jak mogę to zrobić? Daj mi znać, jeśli chcesz, bym podjął dalsze szczegóły lub rozwiał wszelkie wątpliwości.

Dzięki.

+1

+1 Sheesh! Kilka odpowiedzi, ale nie jedna z osób, które odpowiedziały na pytanie, nie zadała sobie trudu? Losowanie oznacza, że ​​pytanie jest dobrze napisane, konkretne i pokazuje, czego użytkownik już próbował. To pytanie spełnia wszystkie wymagania dotyczące przegłosowania. –

+0

@ Jim ... :) Dziękuję! Wow ... fajnie jest mieć kogoś, kto rozpoznaje mnie w ten sposób. Dziękuję bardzo ... Chciałbym, żeby więcej osób myślało jak ty :) Dzięki! +1 za określenie, że moje pytanie spełnia wszystkie wymagania dotyczące przegłosowania. – Hristo

+0

@Jim Garrison masz rację, ale dla mnie są jeszcze dwa wymagania - pytanie powinno być trudne i jest przedmiotem wspólnego zainteresowania - tzn. Gdy masz problem, do tego pytania powinno prowadzić google. – Bozho

Odpowiedz

4

W skrócie, chcę iterować przez HashMap i sprawdzać, czy konkretna nazwa jest przechowywana na którejkolwiek z list. Jak mogę to zrobić?

Istnieją dwa sposoby iteracji mapy, które mogą być interesujące. Po pierwsze, można iterować przez wszystkie odwzorowania (tj. Pary relacji klucz-wartość), korzystając z metody entrySet(), która pozwoli Ci określić, jaki jest klucz dla każdej listy. Ewentualnie, jeśli nie potrzebujesz klucza, możesz po prostu uzyskać wszystkie listy po kolei za pomocą metody values(). Korzystanie z pierwszej opcji może wyglądać tak:

for (Map.Entry<String, ArrayList<String>> entry : theAccused.entrySet()) 
{ 
    String sListName = entry.getKey(); 
    ArrayList<String> saAccused = entry.getValue(); 
    if (saAccused.contains(sAccuser)) 
    { 
     // Fire your logic for when you find a match, which can 
     // depend on the list's key (name) as well 
    } 
} 

Aby odpowiedzieć na szersze pytania - interfejs Set prostu reprezentuje (nieuporządkowana) zbiór wartości spoza duplikowane. Jak widać w połączonej Javadoc, istnieją dostępne metody, których można oczekiwać w przypadku takiej kolekcji nieuporządkowanej. Obiekt Iterator jest obiektem, który przechodzi przez pewną strukturę danych, przedstawiając kolejno każdy element.Typowe użycie iteratora mogłoby wyglądać tak:

Iterator<?> it = ...; // get the iterator somehow; often by calling iterator() on a Collection 
while (it.hasNext()) 
{ 
    Object obj = it.next(); 
    // Do something with the obj 
} 

czyli sprawdzić, czy jest nonexhausted iterator (ma więcej elementów), a następnie wywołać metodę next() dostać ten element. Jednakże, ponieważ powyższy wzorzec jest tak powszechny, można go wyeliminować za pomocą Java 5-go foreach loop, oszczędzając przed zajęciem się samym iteratorem, co wykorzystałem w moim pierwszym przykładzie.

+0

Wow ... Dzięki za odpowiedź! Szybkie pytanie ... kiedy mówisz "Iterater it = ...;", czy jest równy elementowi, w moim przypadku jest równy elementowi z zestawu? Dziękuję za link do "dla każdego". Nigdy tego nie używałem. Gwiezdna odpowiedź! – Hristo

+0

Również ... jeśli wrócimy do pętli for ... jeśli znajdę dopasowanie, w jaki sposób mogę wydobyć nazwę (klucz) z tablicy ArrayList, która zawiera "sAccuser"? – Hristo

+1

@Hristo - zmienna 'it' będzie obiektem, który będzie zwracał kolejne elementy zbioru bazowego za każdym razem, gdy wywołana zostanie metoda' next() ', a nie sam element. Jeśli chodzi o twoje drugie pytanie, zmodyfikowałem mój przykład, aby pokazać go za pomocą 'entrySet()', ponieważ jest to sposób na iterację na mapie, gdy zależy ci na obu wartościach klawiszy * i *. –

0

Musisz użyć wartości z Iterator.next(), aby indeksować do Map.

String key = iterAccusers.next(); 
saTheAccused = theAccused.get(key); 

Obecnie dostajesz wartości z Map na podstawie iterator, a nie wartości zwracane przez iterator.

3

Coś takiego?

for (List<String> list : theAccused.values()) { 
    if (list.contains("somename")) { 
     // found somename 
    } 
} 
2

ten powinien uczynić to działa:

saTheAccused = theAccused.get(iterAccused.next()); 

Jednakże, aby kod był bardziej czytelny, można mieć albo:

for (List<String> values : theAccused.values()) { 
    if (value.contains(sAcuser)) { 
     .. 
    } 
} 

lub, jeśli potrzebujesz klucza:

for (String key : theAccused.keySet()) { 
    List<String> accused = theAccused.get(key); 
    if (accused.contains(sAccuser)) { 
    } 
} 
+0

Dzięki. Tego właśnie potrzebowałem. Czy poprawiam twoją odpowiedź chociaż ... Szukałem tablicy ArrayList ... Nie chcę, żebyś dostał się z głupiego powodu :) – Hristo

+0

@Hristo dostajesz 'ArrayList', ale odwołujesz się do niego poprzez jego interfejs -' Lista ', która jest uważana za lepszą praktykę (chyba że naprawdę potrzebujesz metod specyficznych dla' ArrayList'). – Bozho

+2

Jeśli potrzebujesz zarówno klucza, jak i wartości, powinieneś użyć entrySet, a nie keySet i get. – ILMTitan

0

Dodać metodę, która to robi:

private String findListWithKeyword(Map<String, ArrayList<String>> map, String keyword) { 
    Iterator<String> iterAccusers = map.keySet().iterator(); 
    while(iterAccusers.hasNext()) { 
     String key = iterAccusers.next(); 
     ArrayList<String> list = theAccused.get(key); 
     if (list.contains(keyword)) { 
     return key; 
     } 
    } 
} 

A kiedy wywołać metodę:

String key = findListWithKeyword(map, "foobar"); 
ArrayList<String> theCorrectList = map.get(key); 
+0

.. dziękuję za odpowiedź. Już piszę metodę, która to robi. To jest punkt mojego pytania :) Szybkie pytanie ... kiedy mówisz 'Iterater iterAccusers = ...;', czy iterAccusers jest równy elementowi, w moim przypadku jest równy elementowi z zestawu, lub czy na początku jest niezainicjowany? – Hristo

+0

Jeszcze jedno pytanie ... jeśli znajdę dopasowanie, jak mogę wyodrębnić nazwę (klucz) z tablicy ArrayList, która zawiera 'sAccuser', do której należy? – Hristo

+0

iterAccusers to Iterator, tzn. Możesz wywołać next() i uzyskać następny element. To jest jak pętla for-each. Iterator NIE jest elementem w zestawie, jest obiektem używanym do iteracji przez zestaw. Co do wyodrębniania klucza. Zamiast zwracać listę, po prostu zwróć klucz. Zobacz edytowany kod. – Jes

0

Brzmi jak trzeba zrobić dwie rzeczy: po pierwsze, dowiedzieć się, czy dana nazwa jest "oskarżony", a po drugie, dowiedzieć się, kim jest oskarżyciel. W tym celu należy powtórzyć obiekty Entry w swojej Mapie.

for (Entry<String, List<String>> entry : theAccused.entrySet()) { 
     if (entry.getValue().contains(accused)) { 
      return entry.getKey(); 
     } 
    } 

    return null; // Or throw NullPointerException, or whatever. 

W tej pętli obiekt Entry przechowuje pojedyncze odwzorowanie klucz-wartość. Zatem entry.getValue() zawiera listę oskarżonych, a entry.getKey() zawiera ich oskarżyciela.

+0

.. co to jest obiekt wejścia? Jeszcze tego nie spotkałem. – Hristo

+0

To właściwie wewnętrzna klasa mapy. Pełna nazwa klasy to java.util.Map.Entry. (JavaDoc jest tutaj: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Map.Entry.html) Z mojego doświadczenia wynika, że ​​jest rzadko używana. Jednak w tym przypadku ładnie działa, a ponieważ jest częścią interfejsu Map API, nie ma powodu, aby go nie używać. – DeathB4Decaf