it-swarm.com.ru

Проверьте в карте списка, если существует значение для конкретного ключа Java 8

В Java 7 у меня есть

Map<String, List<String>> m = new HashMap<String, List<String>>();
boolean result = false;
m.put("Name1", Arrays.asList("abc*1"));
m.put("Name2", Arrays.asList("[email protected]*1"));


for (Map.Entry<String, List<String>> me : m.entrySet()) {
    String key = me.getKey();
    List<String> valueList = me.getValue();
    if (key.equals("Name2"){
        System.out.print("Values: ");
        for (String s : valueList) {
            if(s.contains("@"){
                result = true;
            }
        }
    }
} 

Как я могу получить результат bool для Name2, если он содержит @, используя любое совпадение?

Я пытался использовать следующий код, но я не знаю, как использовать ИТ для конкретного ключа 

result = m.values().stream().anyMatch(v -> v.contains("@"))
4
Marinescu Raluca

Вы можете просто использовать m.get("Name2"), поместить (обнуляемый) результат в Optional и затем использовать отображение:

boolean result = Optional.ofNullable(m.get("Name2"))
    .map(l -> l.stream().anyMatch(s -> s.contains("@")))
    .orElse(false);

Это предпочтительнее, чем циклически повторять набор записей, так как HashMap.get равен O(1), а итерация по набору записей равна O (n).

3
Michael

Сделайте следующее:

boolean result = m.getOrDefault("Name2", Collections.emptyList()).stream()
    .anyMatch(i -> i.contains("@"));

Если Map содержит правильный ключ, проверьте, содержит ли какой-либо из его элементов List as value конкретный символ. Если Map не содержит ключа, смоделируйте пустой Collection, который вообще ничего не содержит, и результат автоматически оценивается как false.

Правка: как предложил @Michael, использование Collections.emptyList() - лучший выбор, чем new ArrayList<>().

7
Nikolas

Как насчет 

String name = "Name1";
boolean result= m.containsKey(name) && m.get(name).stream().anyMatch(a -> a.contains("@"));
2
YCF_L

Попробуй это:

boolean result = m.entrySet().stream()
    .filter(e -> e.getKey().equals(Name2))
    .map(Map.Entry::getValue)
    .flatMap(List::stream)
    .anyMatch(s -> s.contains("@"));
2
Bohemian

создайте поток из entrySet() и затем укажите свои критерии в anyMatch:

result = m.entrySet()
          .stream()
          .anyMatch(v -> Objects.equals("Name2", v.getKey()) && 
               v.getValue().stream().anyMatch(s -> s.contains("@")));

или используя getOrDefault:

result = m.getOrDefault("Name2", Collections.emptyList())
          .stream()
          .anyMatch(s -> s.contains("@"));
1
Aomine

Просто добавьте правильное условие фильтра:

m.entrySet()
.stream()
.anyMatch(entry-> entry.getKey().equals(Name2) && 
   entry.getValue()
.stream()
.anyMatch(string -> string.contains("@"))
.getValue();
1
Vinay Prajapati

Сначала вы должны выполнить фильтрацию по требуемому ключу, затем вы можете использовать anyMatch, чтобы определить, содержит ли значение этого ключа элемент с символом «@»:

result = m.entrySet ()
          .stream ()
          .filter (e->e.getKey ().equals (Name2))
          .anyMatch (e->e.getValue ().stream ().anyMatch (s->s.contains ("@")));
1
Eran

Как насчет этого 

Map<Integer, String> result = hmap.entrySet() 
                             .stream() 
                             .filter(map -> map.getKey().equals("Name2")) 
                             .collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()))
                             .orElse(null);

Это также обрабатывает NoSuchElementException.

0
Vinay Hegde