Руководство по Guava RangeMap
1. обзор
В этом руководстве мы покажем, как использовать интерфейсRangeMap Google Guava и его реализации.
RangeMap - это особый вид отображения непересекающихся непустых диапазонов в ненулевые значения. Используя запросы, мы можем посмотреть значение для любого конкретного диапазона на этой карте.
Базовая реализацияRangeMap - этоTreeRangeMap. Внутренне карта используетTreeMap для хранения ключа как диапазона и значения как любого настраиваемого объекта Java.
2. RangeMap в Google Guava
Давайте посмотрим, как использовать классRangeMap.
2.1. Maven Dependency
Начнем с добавления зависимости библиотеки Google Guava вpom.xml:
com.google.guava
guava
21.0
Последнюю версию зависимости можно проверитьhere.
3. Создание
Вот некоторые из способов, которыми мы можем создать экземплярRangeMap:
-
Используйте методcreate из классаTreeRangeMap, чтобы создать изменяемую карту:
RangeMap experienceRangeDesignationMap
= TreeRangeMap.create();
-
Если мы намерены создать неизменяемую карту диапазонов, используйте классImmutableRangeMap (который следует шаблону построителя):
RangeMap experienceRangeDesignationMap
= new ImmutableRangeMap.builder()
.put(Range.closed(0, 2), "Associate")
.build();
4. С помощью
Начнем с простого примера, показывающего использованиеRangeMap.
4.1. Получение на основе ввода в пределах диапазона
Мы можем получить значение, связанное со значением в диапазоне целых чисел:
@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));
}
Замечания:
-
Методclosed классаRange предполагает, что диапазон целочисленных значений находится в диапазоне от 0 до 2 (оба включительно)
-
Range в приведенном выше примере состоит из целых чисел. Мы можем использовать диапазон любого типа, если он реализует интерфейсComparable, такой какString,Character, десятичные числа с плавающей запятой и т. Д.
-
RangeMap возвращаетNull, когда мы пытаемся получить значение для диапазона, которого нет на карте
-
В случаеImmutableRangeMap диапазон одного ключа не может перекрываться с диапазоном ключа, который необходимо вставить. Если это произойдет, мы получимIllegalArgumentException
-
И ключи, и значения вRangeMap не могут бытьnull. Если один из нихnull,, мы получаемNullPointerException
4.2. Удаление значения на основеRange
Давайте посмотрим, как мы можем удалить значения. В этом примере мы покажем, как удалить значение, связанное со всем диапазоном. Мы также покажем, как удалить значение, основанное на частичном диапазоне ключей:
@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));
}
Как видно, даже после частичного удаления значений из диапазона, мы все равно можем получить значения, если диапазон все еще действителен.
4.3. Диапазон ключевого диапазона
В случае, если мы хотели бы знать, каков общий диапазонRangeMap, мы можем использовать методspan:
@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. ПолучениеSubRangeMap
Когда мы хотим выбрать часть изRangeMap, мы можем использовать методsubRangeMap:
@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")));
}
Этот метод возвращает пересечениеRangeMap с заданным параметромRange.
4.5. ПолучениеEntry
Наконец, если мы ищемEntry изRangeMap, мы используем методgetEntry:
@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. Заключение
В этом руководстве мы проиллюстрировали примеры использованияRangeMap в библиотеке Guava. Он преимущественно используется для получения значения, основанного на ключе, указанном на карте.
Реализацию этих примеров можно найти вthe GitHub project - это проект на основе Maven, поэтому его будет легко импортировать и запускать как есть.