Перейти к основному содержимому

Руководство по набору диапазонов гуавы

· 4 мин. чтения

1. Обзор

В этом руководстве мы покажем, как использовать интерфейс RangeSet Google Guava и его реализации.

RangeSet — это набор, состоящий из нуля или более непустых несвязанных диапазонов. При добавлении диапазона в изменяемый RangeSet все связанные диапазоны объединяются, а пустые диапазоны игнорируются.

Базовой реализацией RangeSet является TreeRangeSet .

2. RangeSet Google Guava

Давайте посмотрим, как использовать класс RangeSet .

2.1. Зависимость от Maven

Начнем с добавления зависимости библиотеки Google Guava в pom.xml :

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>

Последнюю версию зависимости можно проверить здесь .

3. Создание

Давайте рассмотрим некоторые способы создания экземпляра RangeSet .

Во-первых, мы можем использовать метод create из класса TreeRangeSet для создания изменяемого набора:

RangeSet<Integer> numberRangeSet = TreeRangeSet.create();

Если у нас уже есть коллекции, используйте метод create из класса TreeRangeSet , чтобы создать изменяемый набор, передав эту коллекцию:

List<Range<Integer>> numberList = Arrays.asList(Range.closed(0, 2));
RangeSet<Integer> numberRangeSet = TreeRangeSet.create(numberList);

Наконец, если нам нужно создать неизменяемый набор диапазонов, используйте класс ImmutableRangeSet (создание которого следует шаблону компоновщика):

RangeSet<Integer> numberRangeSet 
= new ImmutableRangeSet.<Integer>builder().add(Range.closed(0, 2)).build();

4. Использование

Начнем с простого примера, демонстрирующего использование RangeSet .

4.1. Добавление к диапазону

Мы можем проверить, находится ли предоставленный ввод в пределах диапазона, присутствующего в любом из элементов диапазона в наборе:

@Test
public void givenRangeSet_whenQueryWithinRange_returnsSucessfully() {
RangeSet<Integer> numberRangeSet = TreeRangeSet.create();

numberRangeSet.add(Range.closed(0, 2));
numberRangeSet.add(Range.closed(3, 5));
numberRangeSet.add(Range.closed(6, 8));

assertTrue(numberRangeSet.contains(1));
assertFalse(numberRangeSet.contains(9));
}

Заметки:

  • Закрытый метод класса Range предполагает, что диапазон целочисленных значений находится в диапазоне от 0 до 2 (оба включительно).
  • Диапазон в приведенном выше примере состоит из целых чисел. Мы можем использовать диапазон, состоящий из любого типа, если он реализует интерфейс Comparable , такой как String , Character , десятичные числа с плавающей запятой и т. Д.
  • В случае ImmutableRangeSet элемент диапазона, присутствующий в наборе, не может перекрываться с элементом диапазона, который нужно добавить. Если это произойдет, мы получим исключение IllegalArgumentException .
  • Ввод диапазона в RangeSet не может быть нулевым. Если ввод нулевой , мы получим исключение NullPointerException .

4.2. Удаление диапазона

Давайте посмотрим, как мы можем удалить значения из RangeSet :

@Test
public void givenRangeSet_whenRemoveRangeIsCalled_removesSucessfully() {
RangeSet<Integer> numberRangeSet = TreeRangeSet.create();

numberRangeSet.add(Range.closed(0, 2));
numberRangeSet.add(Range.closed(3, 5));
numberRangeSet.add(Range.closed(6, 8));
numberRangeSet.add(Range.closed(9, 15));
numberRangeSet.remove(Range.closed(3, 5));
numberRangeSet.remove(Range.closed(7, 10));

assertTrue(numberRangeSet.contains(1));
assertFalse(numberRangeSet.contains(9));
assertTrue(numberRangeSet.contains(12));
}

Как видно, после удаления мы по-прежнему можем получить доступ к значениям, присутствующим в любом из элементов диапазона, оставшихся в наборе.

4.3. Диапазон Диапазон

Давайте теперь посмотрим, каков общий диапазон RangeSet :

@Test
public void givenRangeSet_whenSpanIsCalled_returnsSucessfully() {
RangeSet<Integer> numberRangeSet = TreeRangeSet.create();

numberRangeSet.add(Range.closed(0, 2));
numberRangeSet.add(Range.closed(3, 5));
numberRangeSet.add(Range.closed(6, 8));
Range<Integer> experienceSpan = numberRangeSet.span();

assertEquals(0, experienceSpan.lowerEndpoint().intValue());
assertEquals(8, experienceSpan.upperEndpoint().intValue());
}

4.4. Получение поддиапазона

Если мы хотим получить часть RangeSet на основе заданного Range , мы можем использовать метод subRangeSet :

@Test
public void
givenRangeSet_whenSubRangeSetIsCalled_returnsSubRangeSucessfully() {

RangeSet<Integer> numberRangeSet = TreeRangeSet.create();

numberRangeSet.add(Range.closed(0, 2));
numberRangeSet.add(Range.closed(3, 5));
numberRangeSet.add(Range.closed(6, 8));
RangeSet<Integer> numberSubRangeSet
= numberRangeSet.subRangeSet(Range.closed(4, 14));

assertFalse(numberSubRangeSet.contains(3));
assertFalse(numberSubRangeSet.contains(14));
assertTrue(numberSubRangeSet.contains(7));
}

4.5. Метод дополнения

Далее, давайте получим все значения, кроме того, которое присутствует в RangeSet , используя метод дополнения :

@Test
public void givenRangeSet_whenComplementIsCalled_returnsSucessfully() {
RangeSet<Integer> numberRangeSet = TreeRangeSet.create();

numberRangeSet.add(Range.closed(0, 2));
numberRangeSet.add(Range.closed(3, 5));
numberRangeSet.add(Range.closed(6, 8));
RangeSet<Integer> numberRangeComplementSet
= numberRangeSet.complement();

assertTrue(numberRangeComplementSet.contains(-1000));
assertFalse(numberRangeComplementSet.contains(2));
assertFalse(numberRangeComplementSet.contains(3));
assertTrue(numberRangeComplementSet.contains(1000));
}

4.6. Пересечение с диапазоном

Наконец, когда мы хотим проверить, пересекается ли интервал диапазона, представленный в RangeSet, с некоторыми или всеми значениями в другом заданном диапазоне, мы можем использовать метод пересечения :

@Test
public void givenRangeSet_whenIntersectsWithinRange_returnsSucessfully() {
RangeSet<Integer> numberRangeSet = TreeRangeSet.create();

numberRangeSet.add(Range.closed(0, 2));
numberRangeSet.add(Range.closed(3, 10));
numberRangeSet.add(Range.closed(15, 18));

assertTrue(numberRangeSet.intersects(Range.closed(4, 17)));
assertFalse(numberRangeSet.intersects(Range.closed(19, 200)));
}

5. Вывод

В этом руководстве мы проиллюстрировали RangeSet библиотеки Guava на нескольких примерах. RangeSet в основном используется для проверки того, попадает ли значение в определенный диапазон, присутствующий в наборе.

Реализацию этих примеров можно найти в проекте GitHub — это проект на основе Maven, поэтому его легко импортировать и запускать как есть.