Use streams for terminating loop over collection conditionally

Total Post:104

 749  View(s)
Rate this:
How to use streams to achieve something like what the following code snippet shows ? Basically, I need to terminate a loop returning one value based on a condition, or returning another value again, based on a condition.

enum Day {

class MyObj {
  Day d;
  public Day getDay();
List<MyObj> myObjList;
Day Myfunc () {
// If atleast one obj belongs to SUNDAY or MONDAY, return.
Day myDay = null;
for(MyObj myObj : myObjList) {
  if(myObj.getDay() == Day.SUNDAY || myObj.getDay() == Day.MONDAY) {
    return myObj.getDay();
  else if (myObj.getDay() == Day.TUESDAY) {
    myDay = myObj.getDay();
return myDay;
  1. Post:397

    Re: Use streams for terminating loop over collection conditionally

    I understand the logic of your function as the following:

    If there's SUNDAY or MONDAY in the input, return the first one of them.
    Otherwise if there's TUESDAY, return it.
    Otherwise return null.
    You can implement this logic in the Java-8 style iterating the list twice and using Optional.orElseGet: -> d == Day.SUNDAY || d == Day.MONDAY)
        .orElseGet(() -> myObjList
            .stream().map(MyObj::getDay).anyMatch(d -> d == Day.TUESDAY) ? Day.TUESDAY : null);
    Looks kinda ugly, so better to stick with the original imperative code.

    An alternative one-pass solution would be to introduce the days priority and use it:

    int priority(Day d) {
        switch(d) {
        case SUNDAY:
        case MONDAY:
            return 10; // max priority
        case TUESDAY:
            return 5;
            return 0;
    Now you can use Stream.max:

            .filter(day -> priority(day) > 0).orElse(null);
    Though it's longer than original code, such solution looks more flexible: you can easily add more cases tweaking the priority method.