Search code examples
guava

Create Guava ImmutableRangeSet from overlapping ranges


Apparently Guava's ImmutableRangeSet cannot store overlapping ranges. This makes sense, but is there an interface to resolve/merge overlapping ranges and then put the resultant ranges into an ImmutableRangeSet?

Currently I'm building a TreeRangeSet, which automatically merges overlapping ranges, and passing this as an argument to ImmutableRangeSet.builder().addAll(). This process works, but it seems a little too indirect just to resolve overlapping ranges.


Solution

  • Can you be more specific about your use case? I guess you have a collection of ranges and you're trying to create ImmutableRangeSet using copyOf method, which throws IAE in case of overlapping ranges. Let's see this test case:

    @Test
    public void shouldHandleOverlappingRanges()
    {
        //given
        ImmutableList<Range<Integer>> ranges = ImmutableList.of(
                Range.closed(0, 2),
                Range.closed(1, 4),
                Range.closed(9, 10)
        );
        //when
        ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.copyOf(ranges);
        //then
        assertThat(rangeSet.asSet(DiscreteDomain.integers()))
                .containsOnly(0, 1, 2, 3, 4, 9, 10);
    }
    

    which fails with

    java.lang.IllegalArgumentException: 
    Overlapping ranges not permitted but found [0..2] overlapping [1..4]
    

    In this case you should use unionOf instead of copyOf and it'd pass:

    //when
    ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.unionOf(ranges);