code: 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;
      }
docs: 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.
  @param input list of key ranges.
  @return reduced list of key ranges.