Эффективный способ найти, содержит ли карта какой-либо из ключей из списка / итерируемых

java arrays dictionary iteration

48797 просмотра

9 ответа

14273 Репутация автора

Мне нужно проверить, содержит ли карта какие-либо ключи из списка, и если это так, то вернуть первое соответствующее значение. Наивный подход, который приходит на ум, состоит в том, чтобы сделать это в двух вложенных циклах:

Map<String, String> fields = new HashMap<String, String>();
fields.put("a", "value a");
fields.put("z", "value z");
String[] candidates = "a|b|c|d".split("|");
for (String key : fields.keySet()){
    for (String candidate : candidates) {
        if (key.equals(candidate)){
            return fields.get(key);
        }
    }
}

Есть ли более приятный и эффективный способ, возможно, основанный на стандартной библиотеке Java?

Автор: ccpizza Источник Размещён: 28.12.2012 11:00

Ответы (9)


24 плюса

34242 Репутация автора

for(String candidate : candidates) {
 if(fields.containsKey(candidate)) {
  return fields.get(candidate)
 }
}

лучший способ, если нулевые значения, возможно, есть в карте, и если требуется только первый обнаруженный ключ.

Автор: NimChimpsky Размещён: 28.12.2012 11:04

7 плюса

31816 Репутация автора

Мой дубль:

Map<String, String> fields = new HashMap<String, String>();
fields.put("a", "value a");
fields.put("z", "value z");
String[] candidates = "a|b|c|d".split("|");
for (String candidate : candidates) {
    if (fields.containsKey(candidate)) {
        return fields.get(candidate);
    }
}
Автор: Petr Janeček Размещён: 28.12.2012 11:04

22 плюса

237702 Репутация автора

Решение

Конечно, что-то вроде:

for (String candidate : candidates) {
     String result = fields.get(key);
     if (result != null) {
         return result;
     }
}

Выше приведен только один поиск карты для каждого ключа-кандидата. Это позволяет избежать отдельного теста на наличие и извлечение, поскольку извлечение несуществующего ключа просто даст вам нулевое значение. Обратите внимание (спасибо Slanec ), что нулевое значение для действительного ключа неотличимо от несуществующего ключа для этого решения.

Я не совсем понимаю, почему вы выполняете преобразование дела, кстати.

Автор: Brian Agnew Размещён: 28.12.2012 11:05

1 плюс

4592 Репутация автора

Map<String, String> fields = new HashMap<String, String>();
fields.put("a", "value a");
fields.put("z", "value z");
String[] candidates = "a|b|c|d".split("|");
List<String> canList = Arrays.asList(candidates );
for (String key : fields.keySet()){

if (canList .contains(key)) {
return fields.get(key);
}

}
Автор: NPKR Размещён: 28.12.2012 11:05

2 плюса

111764 Репутация автора

Попробуй как

    List list= Arrays.asList(1, 2, 3);
    HashMap map = new HashMap();
    map.put(1, 1);
    map.put(3, 3);
    Set set = new HashSet(map.keySet());
    set.retainAll(list);
    System.out.println(set);
    Object e = set.isEmpty() ? null : set.iterator().next();
    System.out.println(e);

выход

[1, 3]
1
Автор: Evgeniy Dorofeev Размещён: 28.12.2012 11:06

5 плюса

6669 Репутация автора

Пытаться

Set<String> keySet = new HashSet<String>(fields.keySet());    
keySet.retainAll(list);

поэтому keySetпредполагается наличие всех ключей из HashMap, которые упомянуты в списке

Автор: Nikolay Kuznetsov Размещён: 28.12.2012 11:09

1 плюс

463335 Репутация автора

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

Автор: Peter Lawrey Размещён: 28.12.2012 11:10

6 плюса

627 Репутация автора

В Java 8 вы можете использовать это:

return candidates.stream()
            .filter(fields::containsKey)
            .findFirst()
            .map(fields::get)
            .orElse(null);
Автор: Klapsa2503 Размещён: 18.11.2016 09:35

8 плюса

110 Репутация автора

В Java 8 вы можете иметь это:

boolean exists = Arrays.stream(candidates).anyMatch(fields::containsKey);

Если вы просто хотите узнать, является ли кто-либо из кандидатов ключевым на карте.

Если вы хотите знать первое или любое другое, вы можете использовать:

Arrays.stream(candidates).filter(fields::containsKey).findAny();

или же

Arrays.stream(candidates).filter(fields::containsKey).findFirst();

Согласно ответу @ Klapsa2503 выше

Автор: mrossini Размещён: 19.01.2017 01:43
Вопросы из категории :
32x32