8

In the below example , someObjects is a set. I am trying to return true if a condition matches within the loop , however this doesn't seem to compile. However when I just add "return" it works fine.What is the issue that I need to fix?

public boolean find(){

    someObjects.forEach(obj -> {
       if (some_condition_met) {
          return true;
       }
    });

    return false;
}

Compilation Errors

The method forEach(Consumer) in the type Iterable is not applicable for the arguments (( obj) -> {})

Punter Vicky
  • 15,954
  • 56
  • 188
  • 315

3 Answers3

16

I guess you want to do this:

public boolean find(){
    return someObjects.stream().anyMatch(o -> your_condition);
}
Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
Jason Hu
  • 6,239
  • 1
  • 20
  • 41
  • Probably not. There's an overhead in building a stream. Much better to do it the old-fashioned (pre Java 8) way. – Dawood ibn Kareem Oct 29 '17 at 21:57
  • 5
    @DawoodibnKareem i assume OP wants something in functional style. judging from his scores, he should know how to do it in the old-fashioned way. – Jason Hu Oct 29 '17 at 21:59
  • 1
    Maybe, but this is clearly a case where the "functional style" is the wrong solution. – Dawood ibn Kareem Oct 29 '17 at 22:00
  • Thank you very much. I'll do the old fashioned way then. – Punter Vicky Oct 29 '17 at 22:01
  • @DawoodibnKareem how can you be so affirmative about it? This solution is perfectly fine. In fact, this is even clearly a case where the functional solution is cleaner and simpler than the old-style one. If it's about the overhead, how is that a problem? You should never use streams if you don't accept their overhead. – Didier L Oct 29 '17 at 23:35
  • 2
    @DidierL I entirely agree with you. real life software practice puts micro performance like this to the very back of the priority queue. there are lots of arguments to object that claim. – Jason Hu Oct 29 '17 at 23:37
  • OK, "wrong" was the wrong word for me to use. How about "not as good"? I would _never_ favour a solution that builds a stream over a solution that doesn't; and I certainly don't find this "cleaner and simpler" than the old-fashioned solution, once you write the lambda out in full. – Dawood ibn Kareem Oct 29 '17 at 23:39
  • 2
    @DawoodibnKareem Considering everything implemented with streams can be rewritten without, by your logic you should never use streams then. – Didier L Oct 29 '17 at 23:41
11

The forEach method in a Collection expects a Consumer which means a function that takes a value, but doesn't return anything. That's why you can't use return true; but a return; works fine.

I you want to break out of the loop when your condition is met, it's better to use a simple for(...) loop. I assumed that the type of obj is Object:

for (Object obj : someObjects) {
  if (some_condition_met) {
    return true;
  }
}

return false;
pablochan
  • 5,625
  • 27
  • 42
4

forEach accepts a Consumer therefore you cannot pass in a behaviour that does not return void. you need to do something like:

return someObjects.stream().anyMatch(e -> condition);
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126