Guia de Goiaba RangeSet

Guia de Goiaba RangeSet

1. Visão geral

Neste tutorial, mostraremos como usar a interfaceRangeSet do Google Guava e suas implementações.

UmRangeSet é um conjunto que compreende zero ou mais faixas não vazias desconectadas. Ao adicionar um intervalo a umRangeSet mutável, todos os intervalos conectados são mesclados, enquanto os intervalos vazios são ignorados.

A implementação básica deRangeSet é umTreeRangeSet.

2. RangeSet do Google Guava

Vamos dar uma olhada em como usar a classeRangeSet.

2.1. Dependência do Maven

Vamos começar adicionando a dependência da biblioteca Guava do Google empom.xml:


    com.google.guava
    guava
    21.0

A versão mais recente da dependência pode ser verificadahere.

3. Criação

Vamos explorar algumas das maneiras pelas quais podemos criar uma instância deRangeSet.

Primeiro, podemos usar o métodocreate da classeTreeRangeSet para criar um conjunto mutável:

RangeSet numberRangeSet = TreeRangeSet.create();

Se já temos coleções no lugar, use o métodocreate da classeTreeRangeSet para criar um conjunto mutável passando essa coleção:

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

Finalmente, se precisarmos criar um conjunto de intervalo imutável, use a classeImmutableRangeSet (criando que segue um padrão de construtor):

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

4. Uso

Vamos começar com um exemplo simples que mostra o uso deRangeSet.

4.1. Adicionando a um intervalo

Podemos verificar se a entrada fornecida está dentro de um intervalo presente em qualquer um dos itens do intervalo em um conjunto:

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

Notas:

  • O métodoclosed da classeRange assume que o intervalo de valores inteiros está entre 0 e 2 (ambos inclusivos)

  • ORange no exemplo acima consiste em inteiros. Podemos usar um intervalo que consiste em qualquer tipo, desde que implemente a interfaceComparable, comoString,Character, decimais de ponto flutuante etc.

  • No caso de umImmutableRangeSet, um item de intervalo presente no conjunto não pode se sobrepor a um item de intervalo que se gostaria de adicionar. Se isso acontecer, obtemos umIllegalArgumentException

  • A entrada de intervalo para umRangeSet não pode ser nula. Se a entrada fornull, teremos umNullPointerException

4.2. Removendo um Alcance

Vamos ver como podemos remover valores de umRangeSet:

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

Como pode ser visto, após a remoção, ainda podemos acessar os valores presentes em qualquer um dos itens de intervalo restantes no conjunto.

4.3. Alcance

Vamos agora ver qual é o intervalo geral de umRangeSet:

@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. Obtendo um Subrange

Se desejarmos obter parte deRangeSet com base em um determinadoRange, podemos usar o métodosubRangeSet:

@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. Método Complemento

A seguir, vamos obter todos os valores, exceto aquele presente emRangeSet, usando o métodocomplement:

@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. Intersecção com um intervalo

Finalmente, quando quisermos verificar se um intervalo de intervalo presente emRangeSet se cruza com alguns ou todos os valores em outro intervalo, podemos fazer uso do métodointersect:

@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. Conclusão

Neste tutorial, ilustramos oRangeSet da biblioteca Guava usando alguns exemplos. ORangeSet é usado predominantemente para verificar se um valor está dentro de um determinado intervalo presente no conjunto.

A implementação desses exemplos pode ser encontrada emthe GitHub project - este é um projeto baseado em Maven, portanto, deve ser fácil de importar e executar como está.