repozoo / range

java library to work with range(s) or interval(s).

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

javadoc License JDK SonarCloud analysis

range


Range is a small java library,
helping to work with range(s) or interval(s).


Usage

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)

Examples

add - 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))
);

remove - Example

// 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))
        );

intersection - 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))
);
// 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))
        );

custom RangeFactory - Example

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);

Maven

<dependency>
  <groupId>io.github.repozoo</groupId>
  <artifactId>range</artifactId>
  <version>1.0.0</version>
</dependency>

Architecture

The most general type is RangeSet, basically representing a list of Ranges.
Why RangeSet? The more specific Range type does not suffice to cover all basic range functionality.
Example: Imagine

  • some range a[1 to 10] and b[3 to 5].
  • a.remove(b) results in (some scattered range) c1[1 to 2] and c2[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 Values from and to (inclusive).
RangeSet as well as Range are both immutable.

range-uml

Basic operations range-api

About

java library to work with range(s) or interval(s).

License:MIT License


Languages

Language:Java 100.0%