Class CaseInsensitiveOrderedMap<V>

All Implemented Interfaces:
Arrangeable, Ordered<CharSequence>, Iterable<Map.Entry<CharSequence,V>>, Map<CharSequence,V>

public class CaseInsensitiveOrderedMap<V> extends ObjectObjectOrderedMap<CharSequence,V>
A custom variant on ObjectObjectOrderedMap 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 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 very similar to CaseInsensitiveMap, except that this class maintains insertion order and can be sorted with ObjectObjectOrderedMap.sort(), ObjectObjectOrderedMap.sortByValue(Comparator), etc. Note that because each CharSequence is stored in here in its original form (not modified to make it ignore case), the sorted order might be different than you expect. Utilities.compareIgnoreCase(CharSequence, CharSequence) can be used to sort this as case-insensitive.
This is also very similar to FilteredStringOrderedMap when its editor is Character.toUpperCase(char) or Casing.caseUp(char). FilteredStringOrderedMap 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 CaseInsensitiveOrderedMap won't do, but new FilteredStringOrderedMap<>(CharPredicates.IS_LETTER, Casing::caseUp will work. 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.
  • Constructor Details

    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(OrderType ordering)
      Creates a new map with an initial capacity of Utilities.getDefaultTableCapacity() and a load factor of Utilities.getDefaultLoadFactor().
      Parameters:
      ordering - determines what implementation ObjectObjectOrderedMap.order() will use
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(int initialCapacity, OrderType ordering)
      Creates a new map with the given starting capacity and a load factor of Utilities.getDefaultLoadFactor().
      Parameters:
      initialCapacity - If not a power of two, it is increased to the next nearest power of two.
      ordering - determines what implementation ObjectObjectOrderedMap.order() will use
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(int initialCapacity, float loadFactor, OrderType ordering)
      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
      ordering - determines what implementation ObjectObjectOrderedMap.order() will use
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(Map<? extends CharSequence,? extends V> map, OrderType ordering)
      Creates a new map identical to the specified map.
      Parameters:
      map - the map to copy
      ordering - determines what implementation ObjectObjectOrderedMap.order() will use
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(ObjectObjectMap<? extends CharSequence,? extends V> map, OrderType ordering)
      Creates a new map identical to the specified map.
      Parameters:
      map - the map to copy
      ordering - determines what implementation ObjectObjectOrderedMap.order() will use
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(ObjectObjectOrderedMap<? extends CharSequence,? extends V> other, int offset, int count, OrderType ordering)
      Creates a new set by copying count items from the given ObjectObjectOrderedMap, starting at offset in that Map, into this.
      Parameters:
      other - another ObjectObjectOrderedMap of the same type
      offset - the first index in other's ordering to draw an item from
      count - how many items to copy from other
      ordering - determines what implementation ObjectObjectOrderedMap.order() will use
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(CharSequence[] keys, V[] values, OrderType ordering)
      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 keys
      values - an array of values
      ordering - determines what implementation ObjectObjectOrderedMap.order() will use
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(Collection<? extends CharSequence> keys, Collection<? extends V> values, OrderType ordering)
      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 keys
      values - a Collection of values
      ordering - determines what implementation ObjectObjectOrderedMap.order() will use
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap()
      Creates a new map with an initial capacity of Utilities.getDefaultTableCapacity() and a load factor of Utilities.getDefaultLoadFactor().
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(int initialCapacity)
      Creates a new map with the specified initial capacity and a load factor of Utilities.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.
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(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
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(Map<? extends CharSequence,? extends V> map)
      Creates a new map identical to the specified map.
      Parameters:
      map - a Map to copy; ObjectObjectOrderedMap and subclasses of it will be faster
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(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. If keys and values have different lengths, this only uses the length of the smaller array.
      Parameters:
      keys - an array of keys
      values - an array of values
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(CaseInsensitiveOrderedMap<? extends V> map)
      Creates a new map identical to the specified map.
      Parameters:
      map - a CaseInsensitiveOrderedMap to copy
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(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. If keys and values have different lengths, this only uses the length of the smaller collection.
      Parameters:
      keys - a Collection of keys
      values - a Collection of values
    • CaseInsensitiveOrderedMap

      public CaseInsensitiveOrderedMap(ObjectObjectOrderedMap<? extends CharSequence,? extends V> other, int offset, int count)
      Creates a new set by copying count items from the given ObjectObjectOrderedMap (or a subclass, such as CaseInsensitiveOrderedMap), starting at offset in that Map, into this.
      Parameters:
      other - another ObjectObjectOrderedMap of the same types (key must be some kind of CharSequence)
      offset - the first index in other's ordering to draw an item from
      count - how many items to copy from other
  • Method Details

    • place

      protected int place(Object item)
      Description copied from class: ObjectObjectMap
      Returns an index >= 0 and <= ObjectObjectMap.mask for the specified item, mixed.
      Overrides:
      place in class ObjectObjectMap<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

      protected boolean equate(Object left, Object right)
      Description copied from class: ObjectObjectMap
      Compares 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 returns left.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:
      equate in class ObjectObjectMap<CharSequence,V>
      Parameters:
      left - must be non-null; typically a key being compared, but not necessarily
      right - 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:
      hashCode in interface Map<CharSequence,V>
      Overrides:
      hashCode in class ObjectObjectMap<CharSequence,V>
    • equals

      public boolean equals(Object obj)
      Specified by:
      equals in interface Map<CharSequence,V>
      Overrides:
      equals in class ObjectObjectMap<CharSequence,V>
    • keySet

      Description copied from class: ObjectObjectOrderedMap
      Returns a Set view 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 own remove operation), the results of the iteration are undefined. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.

      Note that the same Collection instance is returned each time this method is called. Use the OrderedMapKeys(ObjectObjectOrderedMap) constructor for nested or multithreaded iteration.

      Specified by:
      keySet in interface Map<CharSequence,V>
      Overrides:
      keySet in class ObjectObjectOrderedMap<CharSequence,V>
      Returns:
      a set view of the keys contained in this map
    • with

      public static <V> CaseInsensitiveOrderedMap<V> with(CharSequence key0, V value0)
      Constructs a single-entry map given one key and one value. This is mostly useful as an optimization for ObjectObjectOrderedMap.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 key
      value0 - the first and only value
      Returns:
      a new map containing just the entry mapping key0 to value0
    • with

      public static <V> CaseInsensitiveOrderedMap<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 for ObjectObjectOrderedMap.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 key
      value0 - a V value
      key1 - a K key
      value1 - a V value
      Returns:
      a new map containing entries mapping each key to the following value
    • with

      public static <V> CaseInsensitiveOrderedMap<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 for ObjectObjectOrderedMap.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 key
      value0 - a V value
      key1 - a CharSequence key
      value1 - a V value
      key2 - a CharSequence key
      value2 - a V value
      Returns:
      a new map containing entries mapping each key to the following value
    • with

      public static <V> CaseInsensitiveOrderedMap<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 for ObjectObjectOrderedMap.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 key
      value0 - a V value
      key1 - a CharSequence key
      value1 - a V value
      key2 - a CharSequence key
      value2 - a V value
      key3 - a CharSequence key
      value3 - a V value
      Returns:
      a new map containing entries mapping each key to the following value
    • with

      public static <V> CaseInsensitiveOrderedMap<V> with(CharSequence key0, V value0, Object... rest)
      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 use CaseInsensitiveOrderedMap(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 keys
      value0 - the first value; will be used to determine the type of all values
      rest - 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> CaseInsensitiveOrderedMap<V> parse(String str, String entrySeparator, String keyValueSeparator, PartialParser<V> valueParser)
      Creates a new map by parsing all of str with the given PartialParser for values, with entries separated by entrySeparator, such as ", " and the keys separated from values by keyValueSeparator, such as "=".
      Various PartialParser instances are defined as constants, such as PartialParser.DEFAULT_STRING, and others can be created by static methods in PartialParser, such as PartialParser.objectListParser(PartialParser, String, boolean).
      Parameters:
      str - a String containing parseable text
      entrySeparator - the String separating every key-value pair
      keyValueSeparator - the String separating every key from its corresponding value
      valueParser - a PartialParser that returns a V value from a section of str
    • parse

      public static <V> CaseInsensitiveOrderedMap<V> parse(String str, String entrySeparator, String keyValueSeparator, PartialParser<V> valueParser, boolean brackets)
      Creates a new map by parsing all of str (or if brackets is true, all but the first and last chars) with the given PartialParser for values, with entries separated by entrySeparator, such as ", " and the keys separated from values by keyValueSeparator, such as "=".
      Various PartialParser instances are defined as constants, such as PartialParser.DEFAULT_STRING, and others can be created by static methods in PartialParser, such as PartialParser.objectListParser(PartialParser, String, boolean).
      Parameters:
      str - a String containing parseable text
      entrySeparator - the String separating every key-value pair
      keyValueSeparator - the String separating every key from its corresponding value
      valueParser - a PartialParser that returns a V value from a section of str
      brackets - if true, the first and last chars in str will be ignored
    • parse

      public static <V> CaseInsensitiveOrderedMap<V> parse(String str, String entrySeparator, String keyValueSeparator, PartialParser<V> valueParser, int offset, int length)
      Creates a new map by parsing the given subrange of str with the given PartialParser for values, with entries separated by entrySeparator, such as ", " and the keys separated from values by keyValueSeparator, such as "=".
      Various PartialParser instances are defined as constants, such as PartialParser.DEFAULT_STRING, and others can be created by static methods in PartialParser, such as PartialParser.objectListParser(PartialParser, String, boolean).
      Parameters:
      str - a String containing parseable text
      entrySeparator - the String separating every key-value pair
      keyValueSeparator - the String separating every key from its corresponding value
      valueParser - a PartialParser that returns a V value from a section of str
      offset - the first position to read parseable text from in str
      length - how many chars to read; -1 is treated as maximum length