Рубрики
Без рубрики

Коллекции Apache Commons MapUtils

Узнайте, как использовать MapUtils для выполнения общих операций с картой.

Автор оригинала: baeldung.

1. введение

MapUtils – это один из инструментов, доступных в проекте Apache Commons Collections.

Проще говоря, он предоставляет служебные методы и декораторы для работы с java.util.Map и java.util.SortedMap экземпляры.

2. Настройка

Давайте начнем с добавления зависимости :


    org.apache.commons
    commons-collections4
    4.1

3. Полезные методы

3.1. Создание карты из массива

Теперь давайте настроим массивы, которые мы будем использовать для создания карты:

public class MapUtilsTest {
    private String[][] color2DArray = new String[][] {
        {"RED", "#FF0000"},
        {"GREEN", "#00FF00"},
        {"BLUE", "#0000FF"}
    };
    private String[] color1DArray = new String[] {
        "RED", "#FF0000",
        "GREEN", "#00FF00",
        "BLUE", "#0000FF"
    };
    private Map colorMap;

    //...
}

Давайте посмотрим, как мы можем создать карту из двумерного массива:

@Test
public void whenCreateMapFrom2DArray_theMapIsCreated() {
    this.colorMap = MapUtils.putAll(
      new HashMap<>(), this.color2DArray);

    assertThat(
      this.colorMap, 
      is(aMapWithSize(this.color2DArray.length)));
    
    assertThat(this.colorMap, hasEntry("RED", "#FF0000"));
    assertThat(this.colorMap, hasEntry("GREEN", "#00FF00"));
    assertThat(this.colorMap, hasEntry("BLUE", "#0000FF"));
}

Мы также могли бы использовать одномерный массив. В этом случае массив обрабатывается как ключи и значения в альтернативных индексах:

@Test
public void whenCreateMapFrom1DArray_theMapIsCreated() {
    this.colorMap = MapUtils.putAll(
      new HashMap<>(), this.color1DArray);
    
    assertThat(
      this.colorMap, 
      is(aMapWithSize(this.color1DArray.length / 2)));

    assertThat(this.colorMap, hasEntry("RED", "#FF0000"));
    assertThat(this.colorMap, hasEntry("GREEN", "#00FF00"));
    assertThat(this.colorMap, hasEntry("BLUE", "#0000FF"));
}

3.2. Печать содержимого карты

Много раз во время отладки или в журналах отладки мы хотели бы распечатать всю карту:

@Test
public void whenVerbosePrintMap_thenMustPrintFormattedMap() {
    MapUtils.verbosePrint(System.out, "Optional Label", this.colorMap);
}

И результат:

Optional Label = 
{
    RED = #FF0000
    BLUE = #0000FF
    GREEN = #00FF00
}

Мы также можем использовать debug Print () , который дополнительно печатает типы данных значений.

3.3. Получение значений

MapUtils предоставляет некоторые методы извлечения значения из карты для данного ключа безопасным способом null .

Например, getString() получает Строку из Карты . Значение String получается с помощью toString() . Мы можем дополнительно указать значение по умолчанию, которое будет возвращено, если значение null или если преобразование завершится неудачно:

@Test
public void whenGetKeyNotPresent_thenMustReturnDefaultValue() {
    String defaultColorStr = "COLOR_NOT_FOUND";
    String color = MapUtils
      .getString(this.colorMap, "BLACK", defaultColorStr);
    
    assertEquals(color, defaultColorStr);
}

Обратите внимание, что эти методы являются null -безопасными, т. е. Они могут безопасно обрабатывать параметр null map:

@Test
public void whenGetOnNullMap_thenMustReturnDefaultValue() {
    String defaultColorStr = "COLOR_NOT_FOUND";
    String color = MapUtils.getString(null, "RED", defaultColorStr);
    
    assertEquals(color, defaultColorStr);
}

Здесь color получит значение как COLOR_NOT_FOUND , даже если карта null .

3.4. Инвертирование карты

Мы также можем легко перевернуть карту:

@Test
public void whenInvertMap_thenMustReturnInvertedMap() {
    Map invColorMap = MapUtils.invertMap(this.colorMap);

    int size = invColorMap.size();
    Assertions.assertThat(invColorMap)
      .hasSameSizeAs(colorMap)
      .containsKeys(this.colorMap.values().toArray(new String[] {}))
      .containsValues(this.colorMap.keySet().toArray(new String[] {}));
}

Это приведет к инверсии цветовой карты в :

{
    #00FF00 = GREEN
    #FF0000 = RED
    #0000FF = BLUE
}

Если исходная карта связывает одно и то же значение для нескольких ключей, то после инверсии одно из значений станет ключом случайным образом.

3.5. Нулевые и пустые проверки

Метод isEmpty() возвращает true , если Map является null или пустым.

Метод safeAddToMap() предотвращает добавление нулевых элементов в Карту.

4. Декораторы

Эти методы добавляют дополнительную функциональность к карте|/.

В большинстве случаев рекомендуется не хранить ссылку на оформленную карту .

4.1. Карта фиксированного размера

fixedSizeMap() возвращает карту фиксированного размера, поддержанную данной картой. Элементы могут быть изменены, но не добавлены или удалены:

@Test(expected = IllegalArgumentException.class)
public void whenCreateFixedSizedMapAndAdd_thenMustThrowException() {
    Map rgbMap = MapUtils
      .fixedSizeMap(MapUtils.putAll(new HashMap<>(), this.color1DArray));
    
    rgbMap.put("ORANGE", "#FFA500");
}

4.2. Предикатная карта

Метод predicatedMap() возвращает Map гарантирует, что все удерживаемые элементы соответствуют предоставленному предикату:

@Test(expected = IllegalArgumentException.class)
public void whenAddDuplicate_thenThrowException() {
    Map uniqValuesMap 
      = MapUtils.predicatedMap(this.colorMap, null, 
        PredicateUtils.uniquePredicate());
    
    uniqValuesMap.put("NEW_RED", "#FF0000");
}

Здесь мы указали предикат для значений с помощью PredicateUtils.unique Predicate() . Любая попытка вставить повторяющееся значение в эту карту приведет к java.lang. IllegalArgumentException .

Мы можем реализовать пользовательские предикаты, реализовав интерфейс Predicate .

4.3. Ленивая карта

lazy Map() возвращает карту, значения которой инициализируются при запросе.

Если ключ, переданный методу Map.get(Object) этой карты, отсутствует на карте, экземпляр Transformer будет использоваться для создания нового объекта, который будет связан с запрошенным ключом:

@Test
public void whenCreateLazyMap_theMapIsCreated() {
    Map intStrMap = MapUtils.lazyMap(
      new HashMap<>(),
      TransformerUtils.stringValueTransformer());
    
    assertThat(intStrMap, is(anEmptyMap()));
    
    intStrMap.get(1);
    intStrMap.get(2);
    intStrMap.get(3);
    
    assertThat(intStrMap, is(aMapWithSize(3)));
}

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

В этом кратком руководстве мы изучили коллекции Apache Commons MapUtils class и рассмотрели различные служебные методы и декораторы, которые могут упростить различные общие операции с картами.

Как обычно, код доступен на GitHub .