Карты — одна из наиболее широко используемых структур данных в Java. Карта — это коллекция, содержащая пары ключ-значение. Одним из требований является то, что ключи карты должны быть неизменяемыми.
Из-за своей неизменяемой природы строки широко используются в качестве ключей в картах. По умолчанию ключи строк в карте чувствительны к регистру. В этом руководстве будет показано, как создать карту с ключами, нечувствительными к регистру.
1. Карты с учетом регистра и без учета регистра
Давайте сначала разберемся в основной разнице между картой, чувствительной к регистру, и картой, нечувствительной к регистру.
Как упоминалось ранее, по умолчанию ключи будут чувствительны к регистру. Предположим, у нас есть Карта со строкой в качестве ключа и целыми числами в качестве значений. Давайте добавим запись в Карту.
caseSensitiveMap.put("A", 1); //{A=1}
Давайте добавим еще одну запись с тем же ключом, но в маленькой нотации регистра. Поскольку ключи чувствительны к регистру, они будут рассматриваться как отдельные ключи. Теперь содержимое Map будет {A=1, a=2}.
caseSensitiveMap.put("A", 1); //{A=1}caseSensitiveMap.put("a", 2); //{A=1, a=2}
Теперь повторите то же самое с картой, нечувствительной к регистру. Мы добавим те же записи в эту карту. Поскольку ключи нечувствительны к регистру, «A» и «a» будут рассматриваться как одни и те же ключи.
caseInsensitiveMap.put("A", 1); //{A=1}caseInsensitiveMap.put("a", 2); //{A=2}
2. Создание карт без учета регистра
2.1 Использование TreeMap с компаратором CASE_INSENSITIVE_ORDER
TreeMap обеспечивает эффективный способ хранения пар ключ/значение в отсортированном порядке. TreeMap не допускает нулевые ключи. Поскольку TreeMap хранит ключи в отсортированном порядке, мы можем указать порядок сортировки с помощью Comparator, который для нашего варианта использования будет String.CASE_INSENSITIVE_ORDER.
String.CASE_INSENSITIVE_ORDER возвращает Comparator, который сравнивает две строки, игнорируя их регистр. Поскольку регистр ключей будет игнорироваться, мы найдем только одну запись в Map.
Map<String, Integer> caseInsensitiveTreeMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);caseInsensitiveTreeMap.put("AA", 1); //{AA=1}caseInsensitiveTreeMap.put("aa", 2); //{AA=2}
Мы также можем проверить нечувствительную к регистру природу, удалив ключ в другом регистре. После этого удаления размер Map будет равен нулю.
caseInsensitiveTreeMap.remove("aA"); //Remove the entry from map
TreeMap не обеспечивает постоянную производительность для базовых операций, таких как get() и put(). Это не проблема для большинства приложений, но стоит иметь в виду, если у нас есть приложение, критичное к производительности.
2.2. Использование CaseInsensitiveMap
Класс CaseInsensitiveMap является частью Apache Commons Collections. Поскольку это внешняя библиотека, добавьте ее последнюю зависимость из репозитория Maven. Если вы используете Maven, добавьте зависимость следующим образом:
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.4</version></dependency>
CaseInsensitiveMap хранит ключи в нижнем регистре. Также поддерживаются нулевые ключи.
Map<String, Integer> caseInsensitiveMap = new CaseInsensitiveMap<>();caseInsensitiveMap.put("A", 1); //{A=1}caseInsensitiveMap.put("B", 2); //{A=1, B=2}caseInsensitiveMap.put(null, 3); //{A=1, B=2, null=3}caseInsensitiveMap.put("a", 4); //{a=4, B=2, null=3}
Обратите внимание, что клавиша «B» была преобразована в нижний регистр и сохранена в карте как «b».
Опять же, удаление также нечувствительно к регистру ключей.
caseInsensitiveMap.remove("B"); //Removes the entry with key=b
2.3. Использование LinkedCaseInsensitiveMap
Класс LinkedCaseInsensitiveMap является частью Spring Framework. Поскольку Spring — это внешний Framework, его необходимо добавить в ваш classpath. Если мы используем приложение Spring или Spring Boot, он должен быть уже доступен в нашем classpath
<dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.2.5.RELEASE</version></dependency>
LinkedCaseInsensitiveMap предоставляет реализацию Map без учета регистра, которая оборачивает вокруг java.util.LinkedHashMap. Она поддерживает порядок вставки элементов и сохраняет регистр вставленных ключей, в отличие от CaseInsensitiveMap Apache Common. Она не допускает нулевые ключи.
Map<String, Integer> linkedCaseInsensitiveMap = new LinkedCaseInsensitiveMap<>();linkedCaseInsensitiveMap.put("A", 1); //{A=1}linkedCaseInsensitiveMap.put("B", 2); //{A=1, B=2}linkedCaseInsensitiveMap.put("a", 4); //{a=4, B=2}
Обратите внимание, что ключ «B» сохраняет регистр. Ключ «a» переопределит «A». Поскольку «a» был вставлен после «B», элементы отображаются в этом порядке.
Мы можем вызвать удаление на этой карте, используя любой регистр.
linkedCaseInsensitiveMap.remove("b"); //Case-insensitive removal
3. Заключение
В этом руководстве по Java были рассмотрены различные способы создания Map без учета регистра. Мы изучили методы с использованием TreeMap, LinkedCaseInsensitiveMap от Spring и CaseInsensitiveMap от Apache common.
Приятного обучения!!