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, така че трябва да е лесно да се импортира и да се изпълнява както е.