private static List < Map . Entry < Double , Double > > reduce ( List < Map . Entry < Double , Double > > input ) { List < Map . Entry < Double , Double > > ranges = new ArrayList <> ( input ) ; ranges . sort ( Comparator . comparingDouble ( Map . Entry :: getKey ) ) ; List < Map . Entry < Double , Double > > result = new ArrayList <> ( ) ; double low = - 1.0 ; double high = - 1.0 ; for ( Map . Entry < Double , Double > range : ranges ) { if ( high < range . getKey ( ) ) { // add previous result and start a new result if prev.high is less than next.low if ( low != - 1.0 && high != - 1.0 ) { result . add ( new AbstractMap . SimpleEntry <> ( low , high ) ) ; } low = range . getKey ( ) ; high = range . getValue ( ) ; } else if ( high == range . getKey ( ) ) { // if adjacent (prev.high == next.low) then update only high high = range . getValue ( ) ; } else { // if prev.high > next.low. // [Note: next.low cannot be less than 0] which means prev.high > 0 assert low >= 0 ; assert high > 0 ; result . add ( new AbstractMap . SimpleEntry <> ( low , high ) ) ; low = range . getKey ( ) ; high = range . getValue ( ) ; } } // add the last range if ( low != - 1.0 && high != - 1.0 ) { result . add ( new AbstractMap . SimpleEntry <> ( low , high ) ) ; } return result ; }
Helper method to compute list of continuous ranges . For example two neighbouring key ranges where range1 . high == range2 . low then they are considered neighbours . This method reduces input range into distinct continuous blocks .