diff --git a/guava-tests/test/com/google/common/collect/RangeTest.java b/guava-tests/test/com/google/common/collect/RangeTest.java index a682c3ba9601..4f96d87d9128 100644 --- a/guava-tests/test/com/google/common/collect/RangeTest.java +++ b/guava-tests/test/com/google/common/collect/RangeTest.java @@ -122,6 +122,33 @@ public void testIsConnected() { assertFalse(Range.closed(3, 5).isConnected(Range.closedOpen(7, 7))); } + public void testOverlaps() { + // shares one or more values + assertTrue(Range.closed(3, 5).overlaps(Range.closed(4, 6))); + assertTrue(Range.closed(3, 5).overlaps(Range.closed(5, 7))); + assertTrue(Range.closed(3, 5).overlaps(Range.closed(3, 5))); + assertTrue(Range.closed(3, 5).overlaps(Range.open(2, 4))); + assertTrue(Range.atLeast(3).overlaps(Range.atMost(3))); + assertTrue(Range.all().overlaps(Range.closed(3, 5))); + + // connected but no shared value + assertFalse(Range.closed(3, 5).overlaps(Range.open(5, 7))); + assertFalse(Range.closedOpen(3, 5).overlaps(Range.closed(5, 7))); + + // disconnected + assertFalse(Range.closed(3, 5).overlaps(Range.closed(7, 9))); + assertFalse(Range.lessThan(3).overlaps(Range.greaterThan(3))); + + // empty ranges overlap nothing, not even themselves + assertFalse(Range.closedOpen(4, 4).overlaps(Range.closed(1, 9))); + assertFalse(Range.closed(1, 9).overlaps(Range.closedOpen(4, 4))); + assertFalse(Range.closedOpen(4, 4).overlaps(Range.closedOpen(4, 4))); + + // symmetry + assertTrue(Range.closed(5, 7).overlaps(Range.closed(3, 5))); + assertFalse(Range.open(5, 7).overlaps(Range.closed(3, 5))); + } + private static void checkContains(Range range) { assertFalse(range.contains(4)); assertTrue(range.contains(5)); diff --git a/guava/src/com/google/common/collect/Range.java b/guava/src/com/google/common/collect/Range.java index 232ef8b159b3..5ef641e3b1d6 100644 --- a/guava/src/com/google/common/collect/Range.java +++ b/guava/src/com/google/common/collect/Range.java @@ -517,6 +517,33 @@ public boolean isConnected(Range other) { && other.lowerBound.compareTo(upperBound) <= 0; } + /** + * Returns {@code true} if there is at least one value {@linkplain #contains contained} by both + * this range and {@code other}; equivalently, if this range and {@code other} have a nonempty + * {@linkplain #intersection intersection}. + * + *

For example: + * + *

    + *
  • {@code [2, 4)} and {@code [5, 7)} do not overlap + *
  • {@code [2, 4)} and {@code [4, 6)} do not overlap: although they are {@linkplain + * #isConnected connected}, the only range enclosed by both is empty + *
  • {@code [2, 4)} and {@code [3, 5)} overlap, because both contain {@code 3} + *
+ * + *

The overlapping relation is symmetric. It is reflexive except that an {@linkplain #isEmpty + * empty} range does not overlap any range, not even itself. + * + *

Note that certain discrete ranges are not considered to overlap even though no elements lie + * "between them": for example, {@code [3, 5]} does not overlap {@code [6, 10]}. In such cases it + * may be desirable to preprocess both ranges with {@link #canonical(DiscreteDomain)} first. + * + * @since NEXT + */ + public boolean overlaps(Range other) { + return isConnected(other) && !intersection(other).isEmpty(); + } + /** * Returns the maximal range {@linkplain #encloses enclosed} by both this range and {@code * connectedRange}, if such a range exists.

AltStyle によって変換されたページ (->オリジナル) /