Search code examples
javaalgorithmintersectionintervalsinterval-intersection

Interval intersection


I wrote a class that checks whether two integer intevals overlap. However I don't like this solution to much. I think that it's possible to do it in a better and simpler way.

public class IntegerInterval implements Interval {
private Integer start;
private Integer end;

public IntegerInterval(Integer start, Integer end) {
    this.start = start;
    this.end = end;
}

public Integer getStart() {
    return start;
}

public Integer getEnd() {
    return end;
}

public boolean isOverlapping(IntegerInterval other) {
    if (other != null) {
        return isInInterval(start, other) || isInInterval(end, other)
                || isInInterval(other.start, this) || isInInterval(other.end, this);
    }
    return false;
}

public boolean isInInterval(Integer number, IntegerInterval interval) {
    if (number != null && interval != null) {
        if(interval.getStart() == null && interval.getEnd() != null) {
            return number.intValue() <= interval.getEnd().intValue();
        }
        if(interval.getStart() != null && interval.getEnd() == null) {
            return number.intValue() >= interval.getStart().intValue();
        }
        if(interval.getStart() == null && interval.getEnd() == null) {
            return true;
        }
        return interval.getStart() <= number && number <= interval.getEnd();
    }
    else if(number == null && interval != null) {
        return interval.getStart() == null && interval.getEnd() == null;
    }
    return false;
}

}


Solution

  • The following code should be simpler:

    public boolean isOverlapping(IntegerInterval other) {
        if (other == null) return false; // for readability's sake, this condition is pulled out
    
        // overlap happens ONLY when this's end is on the right of other's start
        // AND this's start is on the left of other's end.
        return (((this.end == null) || (other.start == null) || (this.end.intValue() >= other.start.intValue())) &&
            ((this.start == null) || (other.end == null) || (this.start.intValue() <= other.end.intValue())));
    }
    

    UPDATE If compare by Date as @Adam actually asked, the code would be:

    private static boolean dateRangesAreOverlaping(Date start1, Date end1,
                                                   Date start2, Date end2) {
    return (((end1 == null) || (start2 == null) || end1.after(start2)) &&
             ((start1 == null) || (end2 == null) || start1.before(end2)));
    

    }