Есть ли хороший способ получить Map<String,?> Получить и поставить игнорируя регистр?

Есть ли хороший способ иметь Map<String, ?> получить и поставить игнорирование дела?

8 ответов

Решение

TreeMap расширяет Map и поддерживает пользовательские компараторы.

Строка обеспечивает компаратор без учета регистра по умолчанию.

Так:

final Map<String, ...> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

Компаратор не учитывает локаль. Узнайте больше об этом в его JavaDoc.

Вы можете использовать CaseInsensitiveMap из коллекций Apache Commons.

Можно ли было бы реализовать свои собственные методы переопределения put/get для Map?

public class CaseInsensitiveMap extends HashMap<String, String> {
    ...
    put(String key, String value) {
       super.put(key.toLowerCase(), value);
    }

    get(String key) {
       super.get(key.toLowercase());
    }
}

Этот подход не заставляет вас менять свой "ключевой" тип, но вашу реализацию Map.

Вам нужен класс-оболочка для вашего ключа String с реализацией equals() и hashCode() без учета регистра. Используйте это вместо строки для ключа карты.

См. Пример реализации на http://www.java.happycodings.com/Java_Util_Package/code3.html Я нашел его за 2 минуты поиска в Google. Выглядит разумно для меня, хотя я никогда не использовал его.

На ум приходят три очевидных решения:

  • Перед использованием строки в качестве ключа нормализуйте регистр (не турецкая локаль работает иначе, чем в остальном мире).

  • Используйте специальный тип объекта, предназначенный для использования в качестве ключа. Это распространенная идиома для работы с составными ключами.

  • Используйте TreeMap с Comparator, который не чувствителен к регистру (возможно, ПЕРВИЧНАЯ или ВТОРИЧНАЯ сила java.text.Collator). К сожалению, у библиотеки Java нет эквивалента Comparator для hashCode/equals.

Вы можете использовать мой Apache с лицензией CaseInsensitiveMap, которая обсуждалась здесь. В отличие от версии Apache Commons, она сохраняет регистр ключей. Он реализует контракт карты более строго, чем TreeMap (плюс имеет лучшую параллельную семантику) (подробности см. В комментариях к блогу).

Trove4j может использовать пользовательское хеширование для HashMap. Однако это может повлиять на производительность, учитывая, что хеш-коды не могут быть кэшированы (хотя Trove4j, возможно, нашел способ обойти это?). Объекты обертки (как описано Джоном М.) не имеют этого недостатка кэширования. Также см. Мой другой ответ относительно TreeMap.

Проверьте принятый ответ по ссылке ниже. Как проверить ключ на карте независимо от случая?

Суть в том, что "самое простое решение - просто преобразовать все входные данные в прописные (или строчные) перед вставкой / проверкой. Вы даже можете написать свою собственную оболочку Map, которая будет делать это для обеспечения согласованности".

Другие вопросы по тегам