Apply reduction only if certain condition is met

  • A+
Category:Languages

Is there a way to let the 'reduction' of the reduce() method of Stream be optional?

I want to iterate over a list of Periods and join the periods that overlap and maintain both periods if they don't overlap:

interface Period {     boolean overlaps(Period other); }   List<Period> periods = new ArrayList<>();  periods.stream().reduce(new BinaryOperator<Period>() {     @Override     public Period apply(Period period, Period period2) {         if (period.overlaps(period2)){             // join period and period2 into period.         }else{             "return both"             // don't reduce and maintain period and period2 in the list.         }         return null;     } }); 

 


I don't think you can easily do it with streams alone. With Guava ranges, you can do something like this:

periods.stream()         .map(p -> Range.closedOpen(p.getStart(), p.getEnd()))         .collect(TreeRangeSet::<Integer>create, RangeSet::add, RangeSet::addAll)         .asRanges()         .stream()         .map(r -> new PeriodImpl(r.lowerEndpoint(), r.upperEndpoint()))         .collect(Collectors.toList()); 

This assumes a class structure like the following, but you can adjust as necessary:

interface Period {     int getStart();     int getEnd(); }  class PeriodImpl implements Period {     PeriodImpl(int start, int end) {         //...     }     //... } 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: