Ръководство за Apache Commons MultiValuedMap

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

В този бърз урок ще разгледаме интерфейса MultiValuedMap, предоставен в библиотеката Apache Commons Collections .

MultiValuedMap предоставя прост API за преобразуване на всеки ключ в колекция от стойности в Java. Той е наследник на org.apache.commons.collections4.MultiMap, който е остарял в Commons Collection 4.1.

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

За проектите на Maven трябва да добавим зависимостта commons-collection4 :

 org.apache.commons commons-collections4 4.2 

3. Добавяне на елементи в MultiValuedMap

Можем да добавяме елементи, използвайки методите put и putAll .

Нека започнем със създаването на екземпляр на MultiValuedMap :

MultiValuedMap map = new ArrayListValuedHashMap();

След това нека видим как можем да добавяме елементи един по един, използвайки метода put :

map.put("fruits", "apple"); map.put("fruits", "orange");

В допълнение, нека добавим някои елементи, използвайки метода putAll , който съпоставя ключ към множество елементи в едно повикване:

map.putAll("vehicles", Arrays.asList("car", "bike")); assertThat((Collection) map.get("vehicles")) .containsExactly("car", "bike");

4. Извличане на елементи от MultiValuedMap

MultiValuedMap предоставя методи за извличане на ключове, стойности и съпоставяния ключ-стойност. Нека да разгледаме всеки от тях.

4.1. Вземете всички стойности на ключ

За да получим всички стойности, свързани с ключ, можем да използваме метода get , който връща Collection :

assertThat((Collection) map.get("fruits")) .containsExactly("apple", "orange");

4.2. Вземете всички съпоставяния ключ-стойност

Или можем да използваме метода entries , за да получим Колекция от всички съпоставяния ключ-стойност, съдържащи се в картата:

Collection
    
      entries = map.entries();
    

4.3. Вземете всички ключове

Има два метода за извличане на всички ключове, съдържащи се в MultiValuedMap.

Нека използваме метода ключове , за да получим изглед MultiSet на ключовете:

MultiSet keys = map.keys(); assertThat(keys).contains("fruits", "vehicles");

Като алтернатива можем да получим изглед Set на ключовете, използвайки метода keySet :

Set keys = map.keySet(); assertThat(keys).contains("fruits", "vehicles");

4.4. Вземете всички стойности на картата

И накрая, ако искаме да получим колекционен изглед на всички стойности, съдържащи се в картата, можем да използваме метода на стойностите :

Collection values = map.values(); assertThat(values).contains("apple", "orange", "car", "bike");

5. Премахване на елементи от MultiValuedMap

Сега, нека разгледаме всички методи за премахване на елементи и съпоставяния ключ-стойност.

5.1. Премахнете всички елементи, съпоставени с ключ

Първо, нека видим как да премахнем всички стойности, свързани с определен ключ, като използваме метода за премахване :

Collection removedValues = map.remove("fruits"); assertThat(map.containsKey("fruits")).isFalse(); assertThat(removedValues).contains("apple", "orange");

Този метод връща колекционен изглед на премахнатите стойности.

5.2. Премахнете едно картографиране на стойност ключ-стойност

Сега, да предположим, че имаме ключ, съотнесен към множество стойности, но искаме да премахнем само една от картографираните стойности, оставяйки останалите. Лесно можем да направим това, като използваме метода removeMapping :

boolean isRemoved = map.removeMapping("fruits","apple"); assertThat(map.containsMapping("fruits","apple")).isFalse();

5.3. Премахнете всички съпоставяния ключ-стойност

И накрая, можем да използваме метода clear , за да премахнем всички съпоставяния от картата:

map.clear(); assertThat(map.isEmpty()).isTrue();

6. Проверка на елементи от MultiValuedMap

Next, let's take a look at the various methods for checking whether a specified key or value exists in our map.

6.1. Check If a Key Exists

To find out whether our map contains a mapping for a specified key, we can use the containsKey method:

assertThat(map.containsKey("vehicles")).isTrue();

6.2. Check If a Value Exists

Next, suppose we want to check if at least one key in our map contains a mapping for a particular value. We can do this using the containsValue method:

assertThat(map.containsValue("orange")).isTrue();

6.3. Check If a Key-Value Mapping Exists

Similarly, if we want to check whether a map contains a mapping for a specific key and value pair, we can use the containsMapping method:

assertThat(map.containsMapping("fruits","orange")).isTrue();

6.4. Check If a Map Is Empty

To check if a map does not contain any key-value mappings at all, we can use the isEmpty method:

assertThat(map.isEmpty()).isFalse;

6.5. Check the Size of a Map

Finally, we can use the size method to get the total size of the map. When a map has keys with multiple values, then the total size of the map is the count of all the values from all keys:

assertEquals(4, map.size());

7. Implementations

The Apache Commons Collections Library also provides multiple implementations of this interface. Let's have a look at them.

7.1. ArrayListValuedHashMap

An ArrayListValuedHashMap uses an ArrayList internally for storing the values associated with each key, so it allows duplicate key-values pairs:

MultiValuedMap map = new ArrayListValuedHashMap(); map.put("fruits", "apple"); map.put("fruits", "orange"); map.put("fruits", "orange"); assertThat((Collection) map.get("fruits")) .containsExactly("apple", "orange", "orange");

Now, it's worth noting that this class is not thread-safe. Therefore, if we want to use this map from multiple threads, we must be sure to use proper synchronization.

7.2. HashSetValuedHashMap

A HashSetValuedHashMap uses a HashSet for storing the values for each given key. Therefore, it doesn't allow duplicate key-value pairs.

Let's see a quick example, where we add the same key-value mapping twice:

MultiValuedMap map = new HashSetValuedHashMap(); map.put("fruits", "apple"); map.put("fruits", "apple"); assertThat((Collection) map.get("fruits")) .containsExactly("apple");

Notice how, unlike our previous example that used ArrayListValuedHashMap, the HashSetValuedHashMap implementation ignores the duplicate mapping.

The HashSetValuedHashMapclass is also not thread-safe.

7.3. НемодифицируемаMultiValuedMap

В UnmodifiableMultiValuedMap е декоратор клас, което е полезно, когато имаме нужда неизменен инстанция на MultiValuedMap - това е, че не трябва да се позволи по-нататъшни изменения:

@Test(expected = UnsupportedOperationException.class) public void givenUnmodifiableMultiValuedMap_whenInserting_thenThrowingException() { MultiValuedMap map = new ArrayListValuedHashMap(); map.put("fruits", "apple"); map.put("fruits", "orange"); MultiValuedMap immutableMap = MultiMapUtils.unmodifiableMultiValuedMap(map); immutableMap.put("fruits", "banana"); // throws exception }

И отново, заслужава да се отбележи, че модифицирането на окончателния пут ще доведе до UnsupportedOperationException .

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

Виждали сме различни методи на интерфейса MultiValuedMap от библиотеката Apache Commons Collections. Освен това разгледахме няколко популярни внедрения.

И както винаги, пълният изходен код е достъпен в Github.