Range is a small java library,
helping to work with range(s) or interval(s).
You can either
- use predefined Range factories
Range<LocalDate> dateRange = LocalDateRange.between(monday, friday);
Range<LocalDateTime> timeRange = LocalTimeRange.between(now, now.plusHours(8));
- ...
- or create custom ones (see custom RangeFactory - Example)
// Assing
YearMonth dec2021 = YearMonth.parse("2021-12");
RangeSet<LocalDate> vacationSahrah = RangeSet.of(
LocalDateRange.between(dec2021.atDay(1), dec2021.atDay(5)),
LocalDateRange.between(dec2021.atDay(14), dec2021.atDay(26)),
LocalDateRange.between(dec2021.atDay(28), dec2021.atDay(31))
);
RangeSet<LocalDate> vacationJimmy = RangeSet.of(
LocalDateRange.between(dec2021.atDay(1), dec2021.atDay(9)),
LocalDateRange.between(dec2021.atDay(23), dec2021.atDay(29))
);
RangeSet<LocalDate> vacationReggy = RangeSet.of(
LocalDateRange.between(dec2021.atDay(1), dec2021.atDay(9))
);
// Act
RangeSet<LocalDate> atLeastOneIsAbsent = vacationSahrah.add(vacationJimmy).add(vacationReggy);
// Assert
assertThat(atLeastOneIsAbsent.stream())
.containsExactly(
LocalDateRange.between(dec2021.atDay(1), dec2021.atDay(9)),
LocalDateRange.between(dec2021.atDay(14), dec2021.atDay(31))
);
// Assing
YearMonth dec2021 = YearMonth.parse("2021-12");
Range<LocalDate> december = LocalDateRange.between(dec2021.atDay(1), dec2021.atEndOfMonth());
RangeSet<LocalDate> vacationSahrah = RangeSet.of(
LocalDateRange.between(dec2021.atDay(1), dec2021.atDay(5)),
LocalDateRange.between(dec2021.atDay(14), dec2021.atDay(26)),
LocalDateRange.between(dec2021.atDay(28), dec2021.atDay(31))
);
RangeSet<LocalDate> vacationJimmy = RangeSet.of(
LocalDateRange.between(dec2021.atDay(1), dec2021.atDay(9)),
LocalDateRange.between(dec2021.atDay(23), dec2021.atDay(29))
);
// Act
RangeSet<LocalDate> everybodyIsPresent = december.remove(vacationSahrah).remove(vacationJimmy);
// Assert
assertThat(everybodyIsPresent.stream())
.containsExactly(
LocalDateRange.between(dec2021.atDay(10), dec2021.atDay(13))
);
// Assing
YearMonth dec2021 = YearMonth.parse("2021-12");
RangeSet<LocalDate> vacationSahrah = RangeSet.of(
LocalDateRange.between(dec2021.atDay(1), dec2021.atDay(5)),
LocalDateRange.between(dec2021.atDay(14), dec2021.atDay(26)),
LocalDateRange.between(dec2021.atDay(28), dec2021.atDay(31))
);
RangeSet<LocalDate> vacationJimmy = RangeSet.of(
LocalDateRange.between(dec2021.atDay(1), dec2021.atDay(9)),
LocalDateRange.between(dec2021.atDay(23), dec2021.atDay(29))
);
// Act
RangeSet<LocalDate> everybodyIsAbsent = vacationSahrah.intersection(vacationJimmy);
// Assert
assertThat(everybodyIsAbsent.stream())
.containsExactly(
LocalDateRange.between(dec2021.atDay(1), dec2021.atDay(5)),
LocalDateRange.between(dec2021.atDay(23), dec2021.atDay(26)),
LocalDateRange.between(dec2021.atDay(28), dec2021.atDay(29))
);
Let's say we want to create a Range of type YearMonth
and a factory for that type does not exist yet.
//build up the factory
UnaryOperator<YearMonth> next = n -> n.plusMonths(1);
UnaryOperator<YearMonth> previous = n -> n.minusMonths(1);
RangeFactory.CreateRange<YearMonth> createRange = RangeFactory.forType(YearMonth.class)
.withComparator(YearMonth::compareTo)
.withIterator(next, previous)
.build();
YearMonth jan = YearMonth.parse("2022-01");
YearMonth dec = YearMonth.parse("2022-12");
// use it
Range<YearMonth> range = createRange.between(jan, dec);
<dependency>
<groupId>io.github.repozoo</groupId>
<artifactId>range</artifactId>
<version>1.0.0</version>
</dependency>
The most general type is RangeSet
, basically representing a list of Range
s.
Why RangeSet
? The more specific Range
type does not suffice to cover all basic range functionality.
Example: Imagine
- some range
a[1 to 10]
andb[3 to 5]
. a.remove(b)
results in (some scattered range)c1[1 to 2]
andc2[6 to 10]
Therefore RangeSet
is the main building bloc.
The type Range
is just a special RangeSet
containing exactly one Range
and the two Value
s from
and to
(inclusive).
RangeSet
as well as Range
are both immutable.