Guia de Guava RangeMap
1. Visão geral
Neste tutorial, mostraremos como usar a interfaceRangeMap do Google Guava e suas implementações.
UmRangeMap é um tipo especial de mapeamento de intervalos não vazios separados para valores não nulos. Usando consultas, podemos procurar o valor para qualquer intervalo específico nesse mapa.
A implementação básica deRangeMap é umTreeRangeMap. Internamente, o mapa usaTreeMap para armazenar a chave como um intervalo e o valor como qualquer objeto Java personalizado.
2. RangeMap do Google Guava
Vamos dar uma olhada em como usar a classeRangeMap.
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. Criando
Algumas das maneiras pelas quais podemos criar uma instância deRangeMap são:
-
Use o métodocreate da classeTreeRangeMap para criar um mapa mutável:
RangeMap experienceRangeDesignationMap
= TreeRangeMap.create();
-
Se pretendemos criar um mapa de alcance imutável, use a classeImmutableRangeMap (que segue um padrão builder):
RangeMap experienceRangeDesignationMap
= new ImmutableRangeMap.builder()
.put(Range.closed(0, 2), "Associate")
.build();
4. Usando
Vamos começar com um exemplo simples que mostra o uso deRangeMap.
4.1. Recuperação com base na entrada dentro de um intervalo
Podemos obter um valor associado a um valor dentro de um intervalo de números inteiros:
@Test
public void givenRangeMap_whenQueryWithinRange_returnsSucessfully() {
RangeMap experienceRangeDesignationMap
= TreeRangeMap.create();
experienceRangeDesignationMap.put(
Range.closed(0, 2), "Associate");
experienceRangeDesignationMap.put(
Range.closed(3, 5), "Senior Associate");
experienceRangeDesignationMap.put(
Range.closed(6, 8), "Vice President");
experienceRangeDesignationMap.put(
Range.closed(9, 15), "Executive Director");
assertEquals("Vice President",
experienceRangeDesignationMap.get(6));
assertEquals("Executive Director",
experienceRangeDesignationMap.get(15));
}
Nota:
-
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 de qualquer tipo, desde que implemente a interfaceComparable, comoString,Character, decimais de ponto flutuante etc.
-
RangeMap retornaNull quando tentamos obter o valor para um intervalo que não está presente no mapa
-
No caso de umImmutableRangeMap, um intervalo de uma chave não pode se sobrepor a um intervalo de uma chave que precisa ser inserida. Se isso acontecer, obtemos umIllegalArgumentException
-
Tanto as chaves quanto os valores emRangeMap não podem sernull. Se qualquer um deles fornull,, obtemos umNullPointerException
4.2. Removendo um valor com base em umRange
Vamos ver como podemos remover valores. Neste exemplo, mostramos como remover um valor associado a um intervalo inteiro. Também mostramos como remover um valor com base em um intervalo de chaves parcial:
@Test
public void givenRangeMap_whenRemoveRangeIsCalled_removesSucessfully() {
RangeMap experienceRangeDesignationMap
= TreeRangeMap.create();
experienceRangeDesignationMap.put(
Range.closed(0, 2), "Associate");
experienceRangeDesignationMap.put(
Range.closed(3, 5), "Senior Associate");
experienceRangeDesignationMap.put(
Range.closed(6, 8), "Vice President");
experienceRangeDesignationMap.put(
Range.closed(9, 15), "Executive Director");
experienceRangeDesignationMap.remove(Range.closed(9, 15));
experienceRangeDesignationMap.remove(Range.closed(1, 4));
assertNull(experienceRangeDesignationMap.get(9));
assertEquals("Associate",
experienceRangeDesignationMap.get(0));
assertEquals("Senior Associate",
experienceRangeDesignationMap.get(5));
assertNull(experienceRangeDesignationMap.get(1));
}
Como pode ser visto, mesmo após remover parcialmente os valores de um intervalo, ainda podemos obter os valores se o intervalo ainda for válido.
4.3. Extensão do alcance da chave
No caso de desejarmos saber qual é a amplitude geral de umRangeMap, podemos usar o métodospan:
@Test
public void givenRangeMap_whenSpanIsCalled_returnsSucessfully() {
RangeMap experienceRangeDesignationMap = TreeRangeMap.create();
experienceRangeDesignationMap.put(Range.closed(0, 2), "Associate");
experienceRangeDesignationMap.put(Range.closed(3, 5), "Senior Associate");
experienceRangeDesignationMap.put(Range.closed(6, 8), "Vice President");
experienceRangeDesignationMap.put(Range.closed(9, 15), "Executive Director");
experienceRangeDesignationMap.put(Range.closed(16, 30), "Managing Director");
Range experienceSpan = experienceRangeDesignationMap.span();
assertEquals(0, experienceSpan.lowerEndpoint().intValue());
assertEquals(30, experienceSpan.upperEndpoint().intValue());
}
4.4. Obtendo umSubRangeMap
Quando queremos selecionar uma parte de umRangeMap, podemos usar o métodosubRangeMap:
@Test
public void givenRangeMap_whenSubRangeMapIsCalled_returnsSubRangeSuccessfully() {
RangeMap experienceRangeDesignationMap = TreeRangeMap.create();
experienceRangeDesignationMap
.put(Range.closed(0, 2), "Associate");
experienceRangeDesignationMap
.put(Range.closed(3, 5), "Senior Associate");
experienceRangeDesignationMap
.put(Range.closed(6, 8), "Vice President");
experienceRangeDesignationMap
.put(Range.closed(8, 15), "Executive Director");
experienceRangeDesignationMap
.put(Range.closed(16, 30), "Managing Director");
RangeMap experiencedSubRangeDesignationMap
= experienceRangeDesignationMap.subRangeMap(Range.closed(4, 14));
assertNull(experiencedSubRangeDesignationMap.get(3));
assertTrue(experiencedSubRangeDesignationMap.asMapOfRanges().values()
.containsAll(Arrays.asList("Executive Director", "Vice President", "Executive Director")));
}
Este método retorna a interseção deRangeMap com o parâmetroRange fornecido.
4.5. Obtendo umEntry
Finalmente, se estamos procurando umEntry de umRangeMap, usamos o métodogetEntry:
@Test
public void givenRangeMap_whenGetEntryIsCalled_returnsEntrySucessfully() {
RangeMap experienceRangeDesignationMap
= TreeRangeMap.create();
experienceRangeDesignationMap.put(
Range.closed(0, 2), "Associate");
experienceRangeDesignationMap.put(
Range.closed(3, 5), "Senior Associate");
experienceRangeDesignationMap.put(
Range.closed(6, 8), "Vice President");
experienceRangeDesignationMap.put(
Range.closed(9, 15), "Executive Director");
Map.Entry, String> experienceEntry
= experienceRangeDesignationMap.getEntry(10);
assertEquals(Range.closed(9, 15), experienceEntry.getKey());
assertEquals("Executive Director", experienceEntry.getValue());
}
5. Conclusão
Neste tutorial, ilustramos exemplos de uso deRangeMap na biblioteca Guava. É predominantemente usado para obter um valor com base na chave especificada como a do mapa.
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á.