Руководство по 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, поэтому его должно быть легко импортировать и запускать как есть.