Руководство по Guava RangeSet

Руководство по Guava RangeSet

1. обзор

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

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

Базовая реализацияRangeSet - этоTreeRangeSet.

2. RangeSet в Google Guava

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

2.1. Maven Dependency

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


    com.google.guava
    guava
    21.0

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

3. Творчество

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

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

RangeSet numberRangeSet = TreeRangeSet.create();

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

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

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

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

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

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

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

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

@Test
public void givenRangeSet_whenQueryWithinRange_returnsSucessfully() {
    RangeSet 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));
}

Заметки:

  • Методclosed классаRange предполагает, что диапазон целочисленных значений находится в диапазоне от 0 до 2 (оба включительно)

  • Range в приведенном выше примере состоит из целых чисел. Мы можем использовать диапазон, состоящий из любого типа, если он реализует интерфейсComparable, такой какString,Character, десятичные дроби с плавающей запятой и т. Д.

  • В случаеImmutableRangeSet элемент диапазона, присутствующий в наборе, не может перекрываться с элементом диапазона, который нужно добавить. Если это произойдет, мы получимIllegalArgumentException

  • Ввод диапазона вRangeSet не может быть нулевым. Если на входеnull, мы получимNullPointerException

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

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

@Test
public void givenRangeSet_whenRemoveRangeIsCalled_removesSucessfully() {
    RangeSet 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 numberRangeSet = TreeRangeSet.create();

    numberRangeSet.add(Range.closed(0, 2));
    numberRangeSet.add(Range.closed(3, 5));
    numberRangeSet.add(Range.closed(6, 8));
    Range 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 numberRangeSet = TreeRangeSet.create();

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

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

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

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

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

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

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

4.6. Пересечение с полигоном

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

@Test
public void givenRangeSet_whenIntersectsWithinRange_returnsSucessfully() {
    RangeSet 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 преимущественно используется для проверки того, попадает ли значение в определенный диапазон, присутствующий в наборе.

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