public class RangeCombiner {
  private List<Double> mins = new ArrayList<>();
  private List<Double> maxs = new ArrayList<>();

  public void addRange(double min, double max) {
    if (max < min) { return; }
    for (int i = 0; i < mins.size(); i++) {
      if (min <= maxs.get(i)) {
        insertValueAtIndexAndFixForward(min, max, i);
        return;
      }
    }
    // Did not end up merging, new range goes to end
    mins.add(min); maxs.add(max);
  }

  private void insertValueAtIndexAndFixForward(double currMin, double currMax, int i) {
    mins.add(i, currMin); maxs.add(i, currMax);
    // Need to possibly merge it with followup ranges
    // As long as i is not the last index:
    while (i + 1 < mins.size()) {
      Double nextMin = mins.get(i + 1);
      Double nextMax = maxs.get(i + 1);
      if (rangesOverlap(currMin, currMax, nextMin, nextMax)) {
        currMin = Math.min(currMin, nextMin);
        currMax = Math.max(currMax, nextMax);
        mins.set(i, currMin); maxs.set(i, currMax);
        mins.remove(i + 1); maxs.remove(i + 1);
      } else { break; }
    }
  }

  private boolean rangesOverlap(double min1, double max1, double min2, double max2) {
    return (max1 >= min2 && min1 <= min2) || (max2 >= min1 && min2 <= min1);
  }

  boolean isRangeOrderValid() {
    for (int i = 0; i < mins.size() - 1; i++) {
      if (maxs.get(i) >= mins.get(i + 1)) { return false; }
    }
    return true;
  }

  private void printRanges() {
    for (int i = 0; i < mins.size(); i++) {
      System.out.println(String.format("%.2f--%.2f", mins.get(i), maxs.get(i)));
    }
  }

  public static void main(String[] args) {
    RangeCombiner combiner = new RangeCombiner();
    combiner.addRange(2.4, 3.7);
    combiner.addRange(5.6, 5.7);
    combiner.addRange(3.5, 3.8);
    combiner.addRange(6.3, 5.7); // empty range, should ignore
    combiner.addRange(5.7, 5.9);
    combiner.addRange(3.9, 4.1);
    combiner.addRange(3.7, 3.9);
    combiner.addRange(1.1, 1.4); // should appear first
    if (!combiner.isRangeOrderValid()) { System.out.println("Invalid order!"); }
    combiner.printRanges(); // Should print 1.10--1.40, 2.40--4.10 and 5.60--5.90
  }
}
// Transformed
public class RangeCombiner {
  private List<Range> ranges = new ArrayList<>();

  public void addRange(double min, double max) {
    addRangeInternal(new Range(min, max));
  }
  private void addRangeInternal(Range range) {
    if (range.isEmpty()) { return; }
    for (int i = 0; i < ranges.size(); i++) {
      if (range.doesNotFollow(ranges.get(i))) {
        ranges.add(i, range);
        fixForwardFromIndex(i);
        return;
      }
    }
    ranges.add(range);
  }
  private void fixForwardFromIndex(int i) {
    while (i + 1 < ranges.size() && ranges.get(i).overlapsWith(ranges.get(i + 1))) {
      ranges.set(i, ranges.get(i).mergedWith(ranges.get(i + 1)));
      ranges.remove(i + 1);
    }
  }
  boolean isRangeOrderValid() {
    for (int i = 0; i < ranges.size() - 1; i++) {
      if (ranges.get(i + 1).doesNotFollow(ranges.get(i))) { return false; }
    }
    return true;
  }
  private void printRanges() {
    for (Range range : ranges) { System.out.println(range.format()); }
  }

  public static void main(String[] args) {
    RangeCombiner combiner = new RangeCombiner();
    combiner.addRange(2.4, 3.7);
    combiner.addRange(5.6, 5.7);
    combiner.addRange(3.5, 3.8);
    combiner.addRange(6.3, 5.7); // empty range, should ignore
    combiner.addRange(5.7, 5.9);
    combiner.addRange(3.9, 4.1);
    combiner.addRange(3.7, 3.9);
    combiner.addRange(1.1, 1.4); // should appear first
    if (!combiner.isRangeOrderValid()) { System.out.println("Invalid order!"); }
    combiner.printRanges(); // Should print 1.10--1.40, 2.40--4.10 and 5.60--5.90
  }

  private static class Range {
    private final double min;
    private final double max;

    private Range(double min, double max) {
      this.min = min;
      this.max = max;
    }

    private boolean overlapsWith(Range range) {
      return this.doesNotFollow(range) && range.doesNotFollow(this);
    }
    private Range mergedWith(Range range) {
      return new Range(Math.min(min, range.min), Math.max(max, range.max));
    }
    private boolean isEmpty() { return max < min; }
    private boolean doesNotFollow(Range range) { return min <= range.max; }
    private String format() { return String.format("%.2f--%.2f", min, max); }
  }
}