0

I have a nested map as Map<String, Map<String, Boolean>> and would like to find if the inner map has at least one value as TRUE. I was able to do it using a loop but trying to do it using lambda expression

Using for loop:

        Map<String, Map<String, Boolean>> maps = new HashMap<>();
        Map<String, Boolean> test = new HashMap<>();
        test.put("test1", Boolean.FALSE);
        test.put("test2", Boolean.TRUE);
        maps.put("hey", test);
        Map<String, Boolean> testtt = new HashMap<>();
        testtt.put("test3", Boolean.FALSE);
        testtt.put("test4", Boolean.TRUE);
        maps.put("lol", testtt);
        Boolean val = Boolean.FALSE;
        for(Map.Entry<String, Map<String, Boolean>> m: maps.entrySet()){
            Map<String, Boolean> mm = m.getValue();
            for(Map.Entry<String, Boolean> mmm: mm.entrySet()){
                if(mmm.getValue()){
                    val = Boolean.TRUE;
                    break;

                }
            }
        }

        System.out.println(val);
2
  • 1
    but trying to do it using lambda expression Can you please share that attempt? Commented Jan 19, 2023 at 22:00
  • 1
    Even the loop solution can be much simpler: boolean val = false; for(Map<String, Boolean> mm: maps.values()) { if(mm.containsValue(Boolean.TRUE)) { val = true; break; } } Commented Jan 20, 2023 at 9:44

2 Answers 2

3

I was able to do it using a loop but trying to do it using lambda expression.

Here is one way. Here the lambda will be based on a Predicate

  • first you need to stream the outer maps values (which is another map) and then stream the values of those.
  • Then it's a matter of using anyMatch() with an identity lambda to find the first true value.
Predicate<Map<String, Map<String, Boolean>>> hasTrue = m -> m.values()
        .stream().flatMap(map -> map.values().stream()).anyMatch(a->a);

System.out.println(hasTrue.test(maps));

Prints

true

And a better way as suggested by Holger

maps.values().stream()
           .anyMatch(innerMap -> innerMap.containsValue(true))

Sign up to request clarification or add additional context in comments.

Comments

2

You can try changing the loop on something like this:

Map<String, Map<String, Boolean>> maps = new HashMap<>();
boolean hasValue = maps
.values()
.stream()
.flatMap(m -> m.values().stream())
.anyMatch(b -> b.getValue());

4 Comments

Unfortunately, this doesn't compile. The problem is here -> anyMatch(b -> b.getValue(); Did you try to run it?
I couldn't run it. I just sent it over my phone and try to help ASAP, but appreciate your comment. I will try to run it
Since you are streaming over values(), b is already a boolean, hence you can’t call getValue() but there is no need to do. Just anyMatch(b -> b) would do. But it’s still unnecessarily complicated. See this comment
@Holger Thank you, you are right, my misspelling

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.