Ръководство за Guava RangeMap

1. Общ преглед

В този урок ще покажем как да използваме интерфейса RangeMap на Google Guava и неговите реализации.

А RangeMap е специален вид на карти от несвързани непразни диапазони до не-нулеви стойности. Използвайки заявки, можем да търсим стойността за всеки определен диапазон в тази карта.

Основната реализация на RangeMap е TreeRangeMap . Вътрешно картата използва TreeMap, за да съхранява ключа като диапазон и стойността като всеки потребителски Java обект.

2. RangeMap на Google Guava

Нека да разгледаме как да използваме класа RangeMap .

2.1. Зависимост на Maven

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

 com.google.guava guava 29.0-jre 

Най-новата версия на зависимостта може да бъде проверена тук.

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

Забележка:

  • В затворено метода на Range клас поема диапазона от цели числа да бъде между 0 до 2 (включително и двете)
  • На планина в горния пример се състои от цели числа. Можем да използваме диапазон от всякакъв тип, стига той да изпълнява сравним интерфейс като String , Character , десетични знаци с плаваща запетая и т.н.
  • RangeMap връща Null, когато се опитваме да получим стойността за диапазон, който не присъства в map
  • В случай на ImmutableRangeMap , диапазон от един ключ не може да се припокрива с диапазон от ключ, който трябва да бъде вмъкнат. Ако това се случи, получаваме IllegalArgumentException
  • Както ключовете, така и стойностите в RangeMap не могат да бъдат нула . Ако някой от тях е нула, получаваме NullPointerException

4.2. Премахване на стойност въз основа на диапазон

Нека да видим как можем да премахнем стойности. В този пример показваме как да премахнем стойност, свързана с цял диапазон. Ние също така показваме как да премахнем стойност въз основа на частичен диапазон на ключове:

@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. Получаване на запис

И накрая, ако търсим Запис от 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
    
      experienceEntry = experienceRangeDesignationMap.getEntry(10); assertEquals(Range.closed(9, 15), experienceEntry.getKey()); assertEquals("Executive Director", experienceEntry.getValue()); }
    

5. Заключение

В този урок илюстрирахме примери за използване на RangeMap в библиотеката на Guava. Използва се предимно за получаване на стойност въз основа на ключа, посочен като a от картата.

Изпълнението на тези примери може да бъде намерено в проекта GitHub - това е проект, базиран на Maven, така че трябва да е лесно да се импортира и да се изпълнява както е.