Package com.github.tommyettinger.ds
Class CaseInsensitiveMap<V>
java.lang.Object
com.github.tommyettinger.ds.ObjectObjectMap<CharSequence,V>
com.github.tommyettinger.ds.CaseInsensitiveMap<V>
- All Implemented Interfaces:
Iterable<Map.Entry<CharSequence,,V>> Map<CharSequence,V>
A custom variant on ObjectObjectMap that always uses CharSequence keys and compares them as case-insensitive.
This uses a fairly complex, quite-optimized hashing function because it needs to hash CharSequences rather
often, and to do so ignoring case means
This is also very similar to
String.hashCode() won't work, plus not all CharSequences
implement hashCode() themselves (such as StringBuilder). User code similar to this can often get away
with a simple polynomial hash (the typical Java kind, used by String and Arrays), or if more speed is needed,
one with some of these
optimizations by Richard Startin. If you don't want to write or benchmark a hash function (which is quite
understandable), Utilities.hashCodeIgnoreCase(CharSequence) can get a case-insensitive hash of any
CharSequence, as a long. It does this without allocating new Strings all over, where many case-insensitive
algorithms do allocate quite a lot, but it does this by handling case incorrectly for the Georgian alphabet.
If I see Georgian text in-the-wild, I may reconsider, but I don't think that particular alphabet is in
widespread use. There's also Utilities.equalsIgnoreCase(CharSequence, CharSequence) for equality
comparisons that are similarly case-insensitive, except for Georgian.
This is also very similar to
FilteredStringMap when its editor
is Character.toUpperCase(char) or Casing.caseUp(char).
FilteredStringMap works with Strings rather than CharSequences, which
may be more convenient, and allows filtering some characters out of hashing and equality comparisons. If you want a
case-insensitive map that ignores any non-letter characters in a String, then CaseInsensitiveMap won't do,
but new FilteredStringMap<>(CharPredicates.IS_LETTER, Casing::caseUp) will. Note that GWT only handles
Character.isLetter(char) for ASCII letters; CharPredicates in this library provides cross-platform predicates
that use CharBitSet to store their data, and the library RegExodus offers replacements in Category for other
Unicode categories, such as upper-case letters, currency symbols, decimal digits, and so on.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classstatic classNested classes/interfaces inherited from class com.github.tommyettinger.ds.ObjectObjectMap
ObjectObjectMap.Entries<K,V>, ObjectObjectMap.Keys<K, V>, ObjectObjectMap.MapIterator<K, V, I>, ObjectObjectMap.Values<K, V> -
Field Summary
Fields inherited from class com.github.tommyettinger.ds.ObjectObjectMap
defaultValue, entries1, entries2, hashMultiplier, keys1, keys2, keyTable, loadFactor, mask, shift, size, threshold, values1, values2, valueTable -
Constructor Summary
ConstructorsConstructorDescriptionCreates a new map with an initial capacity ofUtilities.getDefaultTableCapacity()and a load factor ofUtilities.getDefaultLoadFactor().CaseInsensitiveMap(int initialCapacity) Creates a new map with the specified initial capacity and a load factor ofUtilities.getDefaultLoadFactor().CaseInsensitiveMap(int initialCapacity, float loadFactor) Creates a new map with the specified initial capacity and load factor.CaseInsensitiveMap(CaseInsensitiveMap<? extends V> map) Creates a new map identical to the specified map.CaseInsensitiveMap(CharSequence[] keys, V[] values) Given two side-by-side arrays, one of keys, one of values, this constructs a map and inserts each pair of key and value into it.CaseInsensitiveMap(Collection<? extends CharSequence> keys, Collection<? extends V> values) Given two side-by-side collections, one of keys, one of values, this constructs a map and inserts each pair of key and value into it.CaseInsensitiveMap(Map<? extends CharSequence, ? extends V> map) Creates a new map identical to the specified map. -
Method Summary
Modifier and TypeMethodDescriptionbooleanprotected booleanCompares the objects left and right, which are usually keys, for equality, returning true if they are considered equal.inthashCode()keySet()Returns aSetview of the keys contained in this map.static <V> CaseInsensitiveMap<V>parse(String str, String entrySeparator, String keyValueSeparator, PartialParser<V> valueParser) Creates a new map by parsing all ofstrwith the given PartialParser for values, with entries separated byentrySeparator, such as", "and the keys separated from values bykeyValueSeparator, such as"=".static <V> CaseInsensitiveMap<V>parse(String str, String entrySeparator, String keyValueSeparator, PartialParser<V> valueParser, boolean brackets) Creates a new map by parsing all ofstr(or ifbracketsis true, all but the first and last chars) with the given PartialParser for values, with entries separated byentrySeparator, such as", "and the keys separated from values bykeyValueSeparator, such as"=".static <V> CaseInsensitiveMap<V>parse(String str, String entrySeparator, String keyValueSeparator, PartialParser<V> valueParser, int offset, int length) Creates a new map by parsing the given subrange ofstrwith the given PartialParser for values, with entries separated byentrySeparator, such as", "and the keys separated from values bykeyValueSeparator, such as"=".protected intReturns an index >= 0 and <=ObjectObjectMap.maskfor the specifieditem, mixed.static <V> CaseInsensitiveMap<V>with(CharSequence key0, V value0) Constructs a single-entry map given one key and one value.static <V> CaseInsensitiveMap<V>with(CharSequence key0, V value0, CharSequence key1, V value1) Constructs a single-entry map given two key-value pairs.static <V> CaseInsensitiveMap<V>with(CharSequence key0, V value0, CharSequence key1, V value1, CharSequence key2, V value2) Constructs a single-entry map given three key-value pairs.static <V> CaseInsensitiveMap<V>with(CharSequence key0, V value0, CharSequence key1, V value1, CharSequence key2, V value2, CharSequence key3, V value3) Constructs a single-entry map given four key-value pairs.static <V> CaseInsensitiveMap<V>with(CharSequence key0, V value0, Object... rest) Constructs a map given alternating keys and values.Methods inherited from class com.github.tommyettinger.ds.ObjectObjectMap
appendTo, appendTo, clear, clear, combine, combine, containsKey, containsValue, containsValue, ensureCapacity, entrySet, equalsIdentity, findKey, findKey, get, getDefaultValue, getHashMultiplier, getLoadFactor, getOrDefault, getTableSize, isEmpty, iterator, locateKey, notEmpty, parse, parse, parse, put, putAll, putAll, putAll, putAll, putAll, putAll, putLegible, putLegible, putLegible, putLegible, putOrDefault, putPairs, putResize, remove, replace, resize, setDefaultValue, setHashMultiplier, setLoadFactor, shrink, size, toString, toString, toString, toString, truncate, values, with, with, with, with, with, withMethods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, waitMethods inherited from interface java.lang.Iterable
forEach, spliteratorMethods inherited from interface java.util.Map
compute, computeIfAbsent, computeIfPresent, forEach, merge, putIfAbsent, remove, replace, replaceAll
-
Constructor Details
-
CaseInsensitiveMap
public CaseInsensitiveMap()Creates a new map with an initial capacity ofUtilities.getDefaultTableCapacity()and a load factor ofUtilities.getDefaultLoadFactor(). -
CaseInsensitiveMap
public CaseInsensitiveMap(int initialCapacity) Creates a new map with the specified initial capacity and a load factor ofUtilities.getDefaultLoadFactor(). This map will hold initialCapacity items before growing the backing table.- Parameters:
initialCapacity- If not a power of two, it is increased to the next nearest power of two.
-
CaseInsensitiveMap
public CaseInsensitiveMap(int initialCapacity, float loadFactor) Creates a new map with the specified initial capacity and load factor. This map will hold initialCapacity items before growing the backing table.- Parameters:
initialCapacity- If not a power of two, it is increased to the next nearest power of two.loadFactor- what fraction of the capacity can be filled before this has to resize; 0 < loadFactor <= 1
-
CaseInsensitiveMap
Creates a new map identical to the specified map.- Parameters:
map- a Map to copy
-
CaseInsensitiveMap
Given two side-by-side arrays, one of keys, one of values, this constructs a map and inserts each pair of key and value into it. If keys and values have different lengths, this only uses the length of the smaller array.- Parameters:
keys- an array of keysvalues- an array of values
-
CaseInsensitiveMap
Creates a new map identical to the specified map.- Parameters:
map- a CaseInsensitiveMap to copy
-
CaseInsensitiveMap
Given two side-by-side collections, one of keys, one of values, this constructs a map and inserts each pair of key and value into it. If keys and values have different lengths, this only uses the length of the smaller collection.- Parameters:
keys- a Collection of keysvalues- a Collection of values
-
-
Method Details
-
place
Description copied from class:ObjectObjectMapReturns an index >= 0 and <=ObjectObjectMap.maskfor the specifieditem, mixed.- Overrides:
placein classObjectObjectMap<CharSequence,V> - Parameters:
item- a non-null Object; its hashCode() method should be used by most implementations- Returns:
- an index between 0 and
ObjectObjectMap.mask(both inclusive)
-
equate
Description copied from class:ObjectObjectMapCompares the objects left and right, which are usually keys, for equality, returning true if they are considered equal. This is used by the rest of this class to determine whether two keys are considered equal. Normally, this returnsleft.equals(right), but subclasses can override it to use reference equality, fuzzy equality, deep array equality, or any other custom definition of equality. Usually,ObjectObjectMap.place(Object)is also overridden if this method is.- Overrides:
equatein classObjectObjectMap<CharSequence,V> - Parameters:
left- must be non-null; typically a key being compared, but not necessarilyright- may be null; typically a key being compared, but can often be null for an empty key slot, or some other type- Returns:
- true if left and right are considered equal for the purposes of this class
-
hashCode
public int hashCode()- Specified by:
hashCodein interfaceMap<CharSequence,V> - Overrides:
hashCodein classObjectObjectMap<CharSequence,V>
-
equals
- Specified by:
equalsin interfaceMap<CharSequence,V> - Overrides:
equalsin classObjectObjectMap<CharSequence,V>
-
keySet
Description copied from class:ObjectObjectMapReturns aSetview of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice versa. If the map is modified while an iteration over the set is in progress (except through the iterator's ownremoveoperation), the results of the iteration are undefined. The set supports element removal, which removes the corresponding mapping from the map, via theIterator.remove,Set.remove,removeAll,retainAll, andclearoperations. It does not support theaddoraddAlloperations.Note that the same Collection instance is returned each time this method is called. Use the
ObjectObjectMap.Keysconstructor for nested or multithreaded iteration.- Specified by:
keySetin interfaceMap<CharSequence,V> - Overrides:
keySetin classObjectObjectMap<CharSequence,V> - Returns:
- a set view of the keys contained in this map
-
with
Constructs a single-entry map given one key and one value. This is mostly useful as an optimization forObjectObjectMap.with(Object, Object, Object...)when there's no "rest" of the keys or values.- Type Parameters:
V- the type of value0- Parameters:
key0- the first and only keyvalue0- the first and only value- Returns:
- a new map containing just the entry mapping key0 to value0
-
with
public static <V> CaseInsensitiveMap<V> with(CharSequence key0, V value0, CharSequence key1, V value1) Constructs a single-entry map given two key-value pairs. This is mostly useful as an optimization forObjectObjectMap.with(Object, Object, Object...)when there's no "rest" of the keys or values.- Type Parameters:
V- the type of value0- Parameters:
key0- a K keyvalue0- a V valuekey1- a K keyvalue1- a V value- Returns:
- a new map containing entries mapping each key to the following value
-
with
public static <V> CaseInsensitiveMap<V> with(CharSequence key0, V value0, CharSequence key1, V value1, CharSequence key2, V value2) Constructs a single-entry map given three key-value pairs. This is mostly useful as an optimization forObjectObjectMap.with(Object, Object, Object...)when there's no "rest" of the keys or values.- Type Parameters:
V- the type of value0- Parameters:
key0- a CharSequence keyvalue0- a V valuekey1- a CharSequence keyvalue1- a V valuekey2- a CharSequence keyvalue2- a V value- Returns:
- a new map containing entries mapping each key to the following value
-
with
public static <V> CaseInsensitiveMap<V> with(CharSequence key0, V value0, CharSequence key1, V value1, CharSequence key2, V value2, CharSequence key3, V value3) Constructs a single-entry map given four key-value pairs. This is mostly useful as an optimization forObjectObjectMap.with(Object, Object, Object...)when there's no "rest" of the keys or values.- Type Parameters:
V- the type of value0- Parameters:
key0- a CharSequence keyvalue0- a V valuekey1- a CharSequence keyvalue1- a V valuekey2- a CharSequence keyvalue2- a V valuekey3- a CharSequence keyvalue3- a V value- Returns:
- a new map containing entries mapping each key to the following value
-
with
Constructs a map given alternating keys and values. This can be useful in some code-generation scenarios, or when you want to make a map conveniently by-hand and have it populated at the start. You can also useCaseInsensitiveMap(CharSequence[], Object[]), which takes all keys and then all values. This needs all keys to have the same type and all values to have the same type, because it gets those types from the first key parameter and first value parameter. Any keys that don't have CharSequence as their type or values that don't have V as their type have that entry skipped.- Type Parameters:
V- the type of values, inferred from value0- Parameters:
key0- the first key; will be used to determine the type of all keysvalue0- the first value; will be used to determine the type of all valuesrest- an array or varargs of alternating CharSequence, V, CharSequence, V... elements- Returns:
- a new map containing the given keys and values
-
parse
public static <V> CaseInsensitiveMap<V> parse(String str, String entrySeparator, String keyValueSeparator, PartialParser<V> valueParser) Creates a new map by parsing all ofstrwith the given PartialParser for values, with entries separated byentrySeparator, such as", "and the keys separated from values bykeyValueSeparator, such as"=".
VariousPartialParserinstances are defined as constants, such asPartialParser.DEFAULT_STRING, and others can be created by static methods in PartialParser, such asPartialParser.objectListParser(PartialParser, String, boolean).- Parameters:
str- a String containing parseable textentrySeparator- the String separating every key-value pairkeyValueSeparator- the String separating every key from its corresponding valuevalueParser- a PartialParser that returns aVvalue from a section ofstr
-
parse
public static <V> CaseInsensitiveMap<V> parse(String str, String entrySeparator, String keyValueSeparator, PartialParser<V> valueParser, boolean brackets) Creates a new map by parsing all ofstr(or ifbracketsis true, all but the first and last chars) with the given PartialParser for values, with entries separated byentrySeparator, such as", "and the keys separated from values bykeyValueSeparator, such as"=".
VariousPartialParserinstances are defined as constants, such asPartialParser.DEFAULT_STRING, and others can be created by static methods in PartialParser, such asPartialParser.objectListParser(PartialParser, String, boolean).- Parameters:
str- a String containing parseable textentrySeparator- the String separating every key-value pairkeyValueSeparator- the String separating every key from its corresponding valuevalueParser- a PartialParser that returns aVvalue from a section ofstrbrackets- if true, the first and last chars instrwill be ignored
-
parse
public static <V> CaseInsensitiveMap<V> parse(String str, String entrySeparator, String keyValueSeparator, PartialParser<V> valueParser, int offset, int length) Creates a new map by parsing the given subrange ofstrwith the given PartialParser for values, with entries separated byentrySeparator, such as", "and the keys separated from values bykeyValueSeparator, such as"=".
VariousPartialParserinstances are defined as constants, such asPartialParser.DEFAULT_STRING, and others can be created by static methods in PartialParser, such asPartialParser.objectListParser(PartialParser, String, boolean).- Parameters:
str- a String containing parseable textentrySeparator- the String separating every key-value pairkeyValueSeparator- the String separating every key from its corresponding valuevalueParser- a PartialParser that returns aVvalue from a section ofstroffset- the first position to read parseable text from instrlength- how many chars to read; -1 is treated as maximum length
-