Проверьте ключи на карте, совпадающие с содержимым Списка в Java

У меня есть List Strings и Map. Каждый ключ на карте должен быть представлен в списке, иначе мне нужно создать исключение. На данный момент я зацикливаю список и проверяю ключ и выбрасываю исключение, если карта не содержит ключ. Ниже приведен пример кода, который я делаю. Есть ли какой-то другой способ в Java8, мы можем сделать это в одну строку или что-то, используя streams и filters?

А также содержимое в списке и ключи на карте должны совпадать. Это я уже обрабатываю в отдельном условии if.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TestClass {

    public static void main(String[] args) {

        List<String> ll = new ArrayList<>();
        Map<String, Integer> m = new HashMap<>();
        ll.add("a");
        ll.add("b");
        ll.add("d");

        m.put("a", 1);
        m.put("b", 1);
        m.put("c", 1);

        if(ll.size() != m.size){
       System.out.println("Throw Exception");
         }

        for(String s : ll) {

            if(!m.containsKey(s)) {
                System.out.println("Throw Exception");
            }
        }
    }
}

Ответы

Ответ 1

Каждый ключ на карте должен быть представлен в списке, иначе мне нужно выдать исключение

Вы можете сделать это, используя Stream.anyMatch и Stream.anyMatch keyset карты вместо этого (имена переменных обновлены для удобства чтения):

if(map.keySet().stream().anyMatch(key -> !list.contains(key))) {
    throw new CustomException("");
}

Лучше и проще, используйте List.containsAll:

if(!list.containsAll(map.keySet())) {
    throw new CustomException("");
} 

Важное замечание: Если вы можете обменять на O(n) пространство, чтобы уменьшить сложность среды выполнения, вы можете создать HashSet из своего List и затем выполнить поиск. Это уменьшит сложность времени выполнения с O(n^2) до O(n) и реализация будет выглядеть так:

Set<String> allUniqueElementsInList = new HashSet<>(list);
if(!allUniqueElementsInList.containsAll(map.keySet())) {
    throw new CustomException("");
}

Ответ 2

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

List<String> ll = new ArrayList<>();
ll.add("a");
ll.add("b");
ll.add("d");

Map<String, Integer> m = new HashMap<>();
m.put("a", 1);
m.put("b", 1);
m.put("c", 1);

Set<String> set = new HashSet<String>(ll);

if (Objects.equals(set, m.keySet())) {
    System.out.println("sets match");
}
else {
    System.out.println("sets do not match");
}

Ответ 3

Просто используйте следующее: -

m.keySet().stream().filter(e -> !ll.contains(e))
                   .findAny()
                   .ifPresent(e -> throwException("Key Not found : " + e));

И определите метод throwException ниже:

public static void throwException(String msg) {
    throw new RuntimeException(msg);
}

Ответ 4

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

if ((ll == null && m == null) ||                            // if both are null
   ((ll.size() == m.size() && m.keySet().containsAll(ll)))  // or contain the same elements
) {
    System.out.println("Collections contain the same elements");
} else {
    throw new CustomException("Collections don't match!");
}

Ответ 5

Вы можете просто изменить существующий код на -

if(!m.keySet().containsAll(ll)) {
    System.out.println("Throws Exception");
}

Это решит вашу проблему. :)

Ответ 6

Вот еще одно решение:

    if (ll  .parallelStream()
            .filter(v -> !m.containsKey(v)) // Filter alle values not contained in the map
            .count() == 0) { // If no values are left then every key was present
        // do something
    } else {
        throw new RuntimeException("hello");
    }

Просто хотел показать другой подход