Home > DeveloperSection > Forums > Use streams for terminating loop over collection conditionally
marcel ethan
marcel ethan

Total Post:105

Points:735
Posted on    December-20-2015 11:16 PM

 Java Java 
Ratings:


 1 Reply(s)
 180  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 {
  SUNDAY, MONDAY, TUESDAY, WEDNESDAY

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


Mayank Tripathi
Mayank Tripathi

Total Post:397

Points:3117
Supported
Posted on    December-21-2015 12:15 AM

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:

myObjList.stream().map(MyObj::getDay).filter(d -> d == Day.SUNDAY || d == Day.MONDAY)
    .findFirst()
    .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;
    default:
        return 0;
    }
}
Now you can use Stream.max:

return myObjList.stream().map(MyObj::getDay).max(Comparator.comparingInt(this::priority))
        .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.

Don't want to miss updates? Please click the below button!

Follow MindStick