sparker
sparker

Reputation: 1578

Check the keys in the map matching with the List content in Java

I have a List of Strings and a Map. Every key in the map needs to present in the list else I need to throw an exception. As of now I am looping the list and checking the key and throw exception if the map doesn't contains the key. Below is the sample code is what I am doing. IS there any other way in Java8 we can do it in one line or something using streams and filters ?

And also the contents in the list and keys in the map should match. That I am already handling in the separate if condition.

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");
            }
        }
    }
}

Upvotes: 14

Views: 6235

Answers (6)

Nicholas K
Nicholas K

Reputation: 15423

Simply use the following :-

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

And define the throwException method below :

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

Upvotes: 2

Naman
Naman

Reputation: 31878

Every key in the map needs to present in the list else I need to throw an exception

You could do it using Stream.anyMatch and iterating on the keyset of the map instead as (variable names updated for readability purpose) :

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

Better and as simple as it gets, use List.containsAll :

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

Important: If you can trade for O(n) space to reduce the runtime complexity, you can create a HashSet out of your List and then perform the lookups. It would reduce the runtime complexity from O(n^2) to O(n) and the implementation would look like:

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

Upvotes: 9

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521168

We can try adding the list to a set, then comparing that set with the keyset from your hashmap:

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");
}

Upvotes: 3

ave4496
ave4496

Reputation: 3018

Here is another solution:

    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");
    }

Just wanted to show a different approach

Upvotes: 1

ETO
ETO

Reputation: 7279

Try this:

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!");
}

Upvotes: 1

prachi
prachi

Reputation: 305

You can simply change your existing code to -

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

This will solve your problem. :)

Upvotes: 1

Related Questions