2013-05-21 12 views
12

Obecnie używam HashMap<String, Integer>, który jest wypełniony klawiszami typu String, które są, powiedzmy, 5 znakami długimi. Jak wyszukać konkretny klucz z 4 znakami lub mniej, który jest częścią i na początku innych kluczy i uzyskać wszystkie trafienia jako kolekcję <Key, Value>?HashMap <String, Integer> Wyszukaj część klucza?

+6

Musisz iterację wszystkich HashMap, użyj 'getKey.length()' i dodać lub nie (w zależności od stanu) do 'List <>' –

+0

Czy spojrzałeś na 'keySet()'? – vikingsteve

+1

Czy jest to zbyt trudne do rozwiązania, jeśli tak, to przynajmniej podziel się tym, czego próbowałeś do tej pory? –

Odpowiedz

20

Iterate jest jedyną opcją, chyba że stworzenie struktury niestandardowych danych:

for (Entry<String, Integer> e : map.entrySet()) { 
    if (e.getKey().startsWith("xxxx")) { 
     //add to my result list 
    } 
} 

Jeśli potrzebujesz czegoś więcej czasu na efektywne wtedy, że potrzebne jest wdrożenie mapie, gdzie jesteś śledzenia tych częściowych klawisze.

0

Z HashMap<String, Integer> można przejść tylko przez keySet() i zrobić dla String klawiszy i swój wzór.

4

Nie możesz tego zrobić poprzez HashMap, powinieneś napisać własną implementację dla Map dla implementacji wyszukiwania opartego na długości łańcucha na mapie.

+0

O ile nie zmienił on wymagań, używa klucza zawierającego tylko 4 znaki i przechowuje inne dane w obiekcie w wartości. Inną opcją jest użycie niestandardowego obiektu klucza z niestandardową metodą hashCode(). –

+0

Nie polecam zwijania własnej mapy <>. To prawdopodobnie przesada (a poza tym kompozycja jest często lepsza niż dziedziczenie). Zgadzam się jednak, że struktura danych, tak jak jest, nie jest przeznaczona do tego. –

+0

Nie musisz implementować całej mapy. Łatwo dodać dodatkowe rzeczy, jeśli użyjesz wzoru dekoratora. Na przykład chcę wylogować każdy klucz dodany do mapy? Dobrze, tworzę mapę LoggingMap Map, a następnie musisz podać rzeczywistą instancję Mapy, którą wyloguje. W tym przypadku działałoby to doskonale, ale zamiast logować się, można śledzić wybrane klucze na liście lub coś podobnego. – cyborg

1

Na przykład:

public static void checkMap(Map mp) { 
    Iterator it = mp.entrySet().iterator(); 
    while (it.hasNext()) { 
     Map.Entry pairs = (Map.Entry)it.next(); 
     System.out.println(pairs.getKey().toLowerCase().contains("YourString")) 
     } 
} 

Ten kod będzie drukować ważne dla tych keys zawierających swoją substring.

+0

Czy potrzebuję funkcji toLowerCase()? W moich kluczach rozróżniana jest wielkość liter. – Machtl

+0

Nie robisz tego, ale używanie metody lowerCase() jest zawsze dobrą praktyką;) –

3
Map<String, Integer> result = new HashMap<String, Integer>; 
for(String key : yourMap.keySet()) { 
    if(key.length() == 4){ 
     result.put(key, yourMap.get(key); 
    } 
} 

Po wykonaniu tego kodu masz wszystkie pary klucz/wartość z 4 klawiszy literowych w result.

1
Set<Entry<String, Integer>> s1 = map.entrySet(); 
    for (Entry<String, Integer> entry : s1) { 
      if(entry.getKey().length == 4) 
      //add it to a map; 
} 

Najpierw pobierz zestaw do swojej mapy. Iteruj przez zestaw i sprawdź długość każdego klawisza i dodaj go do mapy lub użyj go tak, jak chcesz.

4

Wygląda jak przypadek użycia dla TreeMap zamiast HashMap. Różnica polega na tym, że TreeMap zachowuje porządek. Więc możesz znaleźć swój częściowy mecz dużo szybciej. Nie musisz przechodzić przez całą mapę.

Sprawdź to pytanie Partial search in HashMap

0

Jak już wspomniano, nie jest strasznie wydajny * sposób to zrobić z datastructure zostały podane. Jeśli jednak dodasz dodatkowe Map<Integer, List<String>>, aby śledzić mapowanie od długości łańcucha do listy wszystkich kluczy o tej długości, będziesz mógł to zrobić bardzo wydajnie.

* Używanie tylko mapa < String, Integer >, trzeba by wykonać iterację całej pojemności większej mapie, natomiast dodanie tego dodatkowego datastructure wiązałyby się O (1) odnośnika (zakładając, że stosowane HashMap), a następnie przez iterację za pomocą tylko zestawu wyników, który jest najszybszym możliwym wynikiem.

0

Można spróbować tego podejścia:

public Map<String,Integer> filterMap(Map<String, Integer> inputMap){ 
    Map<String, Integer> resultHashMap = new HashMap<String, Integer>(); 
     for (String key : inputMap.keySet()) { 
      if(key.length()==5){ 
       resultHashMap.put(key,inputMap.get(key)); 
      } 
     } 
     return resultHashMap; 
    } 
Powiązane problemy