HashMap‹String, Integer› Искать часть ключа?

В настоящее время я использую HashMap<String, Integer>, который заполнен ключами типа String, которые имеют длину, скажем, 5 символов. Как я могу найти конкретный ключ из 4 символов или меньше, который является частью и в начале некоторых других ключей, и получить все попадания в виде набора <Key, Value>?


person VoidStar    schedule 21.05.2013    source источник
comment
Вы должны перебрать все HashMap, использовать getKey.length() и добавить или нет (в зависимости от условия) к List<>   -  person Javier Diaz    schedule 21.05.2013
comment
Вы смотрели на keySet() ?   -  person vikingsteve    schedule 21.05.2013
comment
Это слишком сложно решить, если да для вас, то, по крайней мере, поделитесь тем, что вы пробовали до сих пор?   -  person Juned Ahsan    schedule 21.05.2013
comment
То, что вы ищете, называется Trie.   -  person Thomas Jungblut    schedule 21.05.2013
comment
Вопрос: он ищет записи, содержащие 4 символа вместо 5? Или он ищет серию из 4 символов, которая может быть в пределах 5 символов?   -  person Menelaos    schedule 21.05.2013
comment
Я отредактировал свой вопрос. Теперь должно быть ясно   -  person VoidStar    schedule 21.05.2013
comment
@Machtl 4 символа в начале или в конце строки)? Могут ли они быть где угодно в строке?   -  person Menelaos    schedule 21.05.2013


Ответы (8)


Итерация — ваш единственный вариант, если вы не создаете пользовательскую структуру данных:

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

Если вам нужно что-то более эффективное по времени, вам понадобится реализация карты, в которой вы отслеживаете эти частичные ключи.

person cyborg    schedule 21.05.2013

Похоже на вариант использования TreeMap, а не HashMap. Разница в том, что TreeMap сохраняет порядок. Так вы сможете найти частичное совпадение гораздо быстрее. Вам не нужно проходить всю карту.

Проверьте этот вопрос Частичный поиск в HashMap

person Ondrej Bozek    schedule 21.05.2013

Вы не можете сделать это через HashMap, вы должны написать свою собственную реализацию для Map для реализации поиска по длине строки на карте.

person harsh    schedule 21.05.2013
comment
Если конечно он не меняет требования, использует ключ только с 4-мя символами, а остальные данные хранит в объекте в значении. Другой вариант — использовать собственный ключевой объект с собственным методом hashCode(). - person Menelaos; 21.05.2013
comment
Я бы не советовал сворачивать собственную Карту‹›. Это, вероятно, излишество (и, кроме того, композиция часто лучше, чем наследование). Однако я согласен с тем, что структура данных как есть не предназначена для этого. - person Michael Aaron Safyan; 21.05.2013
comment
Вам не нужно реализовывать все Map. Довольно легко добавить дополнительные элементы, если вы используете шаблон декоратора. Так, например, я хочу выйти из каждого ключа, добавленного на карту? Хорошо, я делаю свою LoggingMap реализующей Map, а затем вы должны указать фактический экземпляр Map, который будет выходить из системы. В этом случае это будет работать отлично, за исключением того, что вместо регистрации вы будете отслеживать нужные ключи в списке или что-то в этом роде. - person cyborg; 21.05.2013
comment
Да, правильная реализация Map может быть расширением (extends) реализации HashMap или других существующих реализаций, переопределять только то, что требуется. Моя точка зрения заключалась в том, что для этого вопроса Map кажется правильной структурой данных, но с некоторыми измененными get (для поиска на основе длины) и помещенными (для оптимального получения повторите O(1)). Поскольку все остальные ответы показывают внешнюю логику в качестве решения, наличие определенного Map приведет к инкапсуляции этой логики внутри самой карты. - person harsh; 21.05.2013

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

После выполнения этого кода у вас есть все пары ключ/значение с 4-буквенными ключами в result.

person André Stannek    schedule 21.05.2013

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

Сначала установите запись в свою хэш-карту. Переберите набор и проверьте длину каждого ключа и добавьте его на карту или используйте его по своему усмотрению.

person Adarsh    schedule 21.05.2013

С помощью HashMap<String, Integer> вы можете пройти только keySet() и выполнить contains() для String клавиш и вашего паттерна.

person pbespechnyi    schedule 21.05.2013

Как уже отмечалось, не существует очень эффективного* способа сделать это с указанной вами структурой данных. Однако, если вы добавите дополнительный Map<Integer, List<String>> для отслеживания сопоставления длины строки со списком всех ключей с этой длиной, вы сможете сделать это очень эффективно.

*Используя только Map‹String, Integer›, вам нужно будет выполнить итерацию по всей емкости большей карты, тогда как добавление этой дополнительной структуры данных потребует поиска O (1) (при условии, что вы использовали HashMap), за которым следует итерация только через набор результатов, который является самым быстрым результатом.

person Michael Aaron Safyan    schedule 21.05.2013

Вы можете попробовать этот подход:

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;
    }
person Shreyos Adikari    schedule 21.05.2013