Carte Java avec des clés insensibles à la casse

1. Vue d'ensemble

La carte est l'une des structures de données les plus courantes en Java et String est l'un des types les plus courants de clé de carte. Par défaut, une carte de ce type a des clés sensibles à la casse.

Dans ce court didacticiel, nous explorerons différentes implémentations de Map qui acceptent toutes les variations de casse d'une chaîne comme la même clé .

2. Un examen plus approfondi de la carte avec des clés insensibles à la casse

Examinons le problème que nous essayons de résoudre plus en détail.

Supposons que nous ayons une carte avec une entrée:

Ajoutons l'entrée suivante:

map.put("ABC", 2);

Lorsque vous travaillez avec une carte avec des clés sensibles à la casse, nous nous retrouverons avec deux entrées:

Mais lorsque vous travaillez avec une carte avec des clés insensibles à la casse, le contenu sera:

Dans les exemples suivants, nous plongerons dans les implémentations insensibles à la casse de certaines implémentations populaires de Map : TreeMap , HashMap et LinkedHashMap .

3. TreeMap

TreeMap est une implémentation de NavigableMap , ce qui signifie qu'il trie toujours les entrées après insertion, en fonction d'un comparateur donné . De plus, TreeMap utilise un comparateur pour déterminer si une clé insérée est un doublon ou une nouvelle.

Par conséquent, si nous fournissons un comparateur de chaînes insensible à la casse , nous obtiendrons un TreeMap insensible à la casse .

Heureusement, String fournit déjà ce comparateur statique :

public static final Comparator  CASE_INSENSITIVE_ORDER

que nous pouvons fournir dans le constructeur:

Map treeMap = new TreeMap(String.CASE_INSENSITIVE_ORDER); treeMap.put("abc", 1); treeMap.put("ABC", 2);

Et maintenant, lorsque nous exécutons des tests, nous pouvons voir que la taille de la carte est une:

assertEquals(1, treeMap.size());

et la valeur est mise à jour à 2:

assertEquals(2, treeMap.get("aBc").intValue()); assertEquals(2, treeMap.get("ABc").intValue());

Supprimons maintenant l'entrée, en utilisant la même chaîne , mais avec un autre cas:

treeMap.remove("aBC"); assertEquals(0, treeMap.size());

Nous devons garder à l'esprit que des fonctions comme put and get coûtent en moyenne O (log n) pour TreeMap par rapport à un HashMap qui fournit l'insertion et la recherche de O (1).

Il est également intéressant de noter que TreeMap n'autorise pas les clés nulles .

4. CaseInsensitiveMap d'Apache

Commons-Collections Apache est une bibliothèque Java très populaire, fournissant un grand nombre de classes utiles avec CaseInsensitiveMap parmi elles.

CaseInsensitiveMap est une carte basée sur le hachage , qui convertit les clés en minuscules avant qu'elles ne soient ajoutées ou récupérées. Contrairement à TreeMap , CaseInsensitiveMap permet l' insertion de clé nulle .

Tout d'abord, nous devons ajouter la dépendance commons-collections4 :

 org.apache.commons commons-collections4 4.4 

Maintenant, nous pouvons utiliser CaseInsensitiveMap et ajouter deux entrées:

Map commonsHashMap = new CaseInsensitiveMap(); commonsHashMap.put("abc", 1); commonsHashMap.put("ABC", 2);

Lorsque nous le testons, nous attendons les mêmes résultats que nous avons vu précédemment:

assertEquals(1, commonsHashMap.size()); assertEquals(2, commonsHashMap.get("aBc").intValue()); assertEquals(2, commonsHashMap.get("ABc").intValue()); commonsHashMap.remove("aBC"); assertEquals(0, commonsHashMap.size());

5. LinkedCaseInsensitiveMap de Spring

Spring Core est un module Spring Framework qui fournit également des classes utilitaires, y compris LinkedCaseInsensitiveMap .

LinkedCaseInsensitiveMap encapsule un LinkedHashMap , qui est une carte basée sur une table de hachage et une liste liée. Contrairement à LinkedHashMap , il n'autorise pas l' insertion de clé nulle . LinkedCaseInsensitiveMap préserve l'ordre d'origine ainsi que le boîtier d'origine des touches tout en permettant d'appeler des fonctions comme obtenir et supprimer dans tous les cas.

Tout d'abord, ajoutons la dépendance spring-core :

 org.springframework spring-core 5.2.5.RELEASE 

Maintenant, nous pouvons initialiser un nouveau LinkedCaseInsensitiveMap :

Map linkedHashMap = new LinkedCaseInsensitiveMap(); linkedHashMap.put("abc", 1); linkedHashMap.put("ABC", 2);

ajouter le tester:

assertEquals(1, linkedHashMap.size()); assertEquals(2, linkedHashMap.get("aBc").intValue()); assertEquals(2, linkedHashMap.get("ABc").intValue()); linkedHashMap.remove("aBC"); assertEquals(0, linkedHashMap.size());

6. Conclusion

Dans ce didacticiel, nous avons examiné différentes façons de créer une carte Java avec des clés insensibles à la casse et utilisé différentes classes pour l'obtenir.

Comme toujours, le code est disponible sur sur GitHub.