8

I am comparing 2 maps using Java 8 features and based on condition wants to return the result. Using .forEach is showing compile time error and basically, the return is returning from Lambda expression and not from the loop. How can I return from the loop enclosing the lambda?
Note that I am not comparing for equality for the two map objects

nMap.forEach((k,v) -> {
    if (!mMap.containsKey(k) || mMap.get(k) < v) {
        return -1;
    }
});
Abhinav Tyagi
  • 5,158
  • 3
  • 30
  • 60

2 Answers2

8

Use a Stream of the entrySet() and anyMatch instead of forEach:

boolean found = 
    nMap.entrySet()
        .stream()
        .anyMatch(e -> !mMap.containsKey(e.getKey()) || mMap.get(e.getKey()) < e.getValue());
if (found)
    return -1;
Eran
  • 387,369
  • 54
  • 702
  • 768
  • I want to check if all entries in nMap matches the condition. – Abhinav Tyagi Oct 11 '18 at 07:38
  • 2
    @AbhinavTyagi In that case, why did you return -1 the first time your condition was true? Anyway, if you want to check all entries, change anyMatch to allMatch – Eran Oct 11 '18 at 07:39
  • 1
    If you're only using `e.getKey()` in the lambda body, you could just use `nMap.keySet().stream()` instead. (And are you missing a `< v`?) – Andy Turner Oct 11 '18 at 07:56
  • @AndyTurner yes, I must have accidentally deleted it when I formatted my answer. thanks – Eran Oct 11 '18 at 08:09
  • Alternatively: `boolean found = !mMap.keySet().containsAll(nMap.keySet()) || nMap.entrySet().stream() .anyMatch(e -> mMap.get(e.getKey()) < e.getValue());` – Holger Oct 11 '18 at 09:20
2

Another approach using a Stream which filters the entries according to the given condition. The result of the streaming is an Optional which may contain a found Entry:

if (nMap.entrySet().stream()
        .filter(e -> !mMap.containsKey(e.getKey()) || mMap.get(e.getKey()) < e.getValue())
        .findAny()
        .isPresent()) {
    return -1;
}
fps
  • 33,623
  • 8
  • 55
  • 110
LuCio
  • 5,055
  • 2
  • 18
  • 34