Class FilteredIterableMap<K,I extends Iterable<K>,V>

java.lang.Object
com.github.tommyettinger.ds.ObjectObjectMap<I,V>
com.github.tommyettinger.ds.FilteredIterableMap<K,I,V>
All Implemented Interfaces:
Iterable<Map.Entry<I,V>>, Map<I,V>

public class FilteredIterableMap<K,I extends Iterable<K>,V> extends ObjectObjectMap<I,V>
A customizable variant on ObjectMap that uses Iterable keys made of K sub-keys, and only considers a sub-key (for equality and hashing purposes) if that sub-key satisfies a predicate. This can also edit the sub-keys that pass the filter, such as to normalize their data during comparisons (and hashing). You will usually want to call setFilter(ObjPredicate) and/or setEditor(ObjToSameFunction) to change the behavior of hashing and equality before you enter any keys, unless you have specified the filter and/or editor you want in the constructor. Calling setModifiers(ObjPredicate, ObjToSameFunction) is recommended if you need to set both the filter and the editor; you could also set them in the constructor.
This class is related to FilteredStringMap, which can be seen as using a String as a key and the characters of that String as its sub-keys. That means this is also similar to CaseInsensitiveMap, which is essentially a specialized version of FilteredIterableMap (which can be useful for serialization).
  • Field Details

    • filter

      protected com.github.tommyettinger.function.ObjPredicate<K> filter
    • editor

      protected com.github.tommyettinger.function.ObjToSameFunction<K> editor
  • Constructor Details

    • FilteredIterableMap

      public FilteredIterableMap()
      Creates a new map with an initial capacity of Utilities.getDefaultTableCapacity() and a load factor of Utilities.getDefaultLoadFactor(). This considers all sub-keys in an Iterable key and does not edit any sub-keys.
    • FilteredIterableMap

      public FilteredIterableMap(int initialCapacity)
      Creates a new map with the specified initial capacity and a load factor of Utilities.getDefaultLoadFactor(). This set will hold initialCapacity keys before growing the backing table. This considers all sub-keys in an Iterable key and does not edit any sub-keys.
      Parameters:
      initialCapacity - If not a power of two, it is increased to the next nearest power of two.
    • FilteredIterableMap

      public FilteredIterableMap(int initialCapacity, float loadFactor)
      Creates a new map with the specified initial capacity and load factor. This set will hold initialCapacity keys before growing the backing table. This considers all sub-keys in an Iterable key and does not edit any sub-keys.
      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
    • FilteredIterableMap

      public FilteredIterableMap(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor)
      Creates a new map with an initial capacity of Utilities.getDefaultTableCapacity() and a load factor of Utilities.getDefaultLoadFactor(). This uses the specified filter and editor.
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
    • FilteredIterableMap

      public FilteredIterableMap(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, int initialCapacity)
      Creates a new map with the specified initial capacity and a load factor of Utilities.getDefaultLoadFactor(). This set will hold initialCapacity keys before growing the backing table. This uses the specified filter and editor.
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      initialCapacity - If not a power of two, it is increased to the next nearest power of two.
    • FilteredIterableMap

      public FilteredIterableMap(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, int initialCapacity, float loadFactor)
      Creates a new map with the specified initial capacity and load factor. This set will hold initialCapacity keys before growing the backing table. This uses the specified filter and editor.
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      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
    • FilteredIterableMap

      public FilteredIterableMap(FilteredIterableMap<K,? extends I,? extends V> map)
      Creates a new map identical to the specified map.
      Parameters:
      map - another FilteredIterableMap to copy
    • FilteredIterableMap

      public FilteredIterableMap(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, Map<? extends I,? extends V> map)
      Creates a new map with the given filter and editor, and attempts to insert every entry from the given map into the new data structure. Not all keys from map might be entered if the filter and editor consider some as equal.
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      map - a Map to copy
    • FilteredIterableMap

      public FilteredIterableMap(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, Collection<? extends I> 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. This uses the specified filter and editor, including while it enters the keys and values.
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      keys - a Collection of keys
      values - a Collection of values
    • FilteredIterableMap

      public FilteredIterableMap(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, I[] keys, V[] values)
      Creates a new map using all the keys from the given keys and values. This uses the specified filter and editor, including while it enters the keys and values.
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      keys - an array to draw keys from
      values - an array to draw values from
  • Method Details

    • getFilter

      public com.github.tommyettinger.function.ObjPredicate<K> getFilter()
    • setFilter

      public FilteredIterableMap<K,I,V> setFilter(com.github.tommyettinger.function.ObjPredicate<K> filter)
      Sets the filter that determines which sub-keys in an Iterable are considered for equality and hashing, then returns this object, for chaining. ObjPredicate filters could be lambdas or method references that take a sub-key and return true if that sub-key will be used for hashing/equality, or return false to ignore it. The default filter always returns true. If the filter changes, that invalidates anything previously entered into this, so before changing the filter this clears the entire data structure, removing all existing entries.
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      Returns:
      this, for chaining
    • getEditor

      public com.github.tommyettinger.function.ObjToSameFunction<K> getEditor()
    • setEditor

      public FilteredIterableMap<K,I,V> setEditor(com.github.tommyettinger.function.ObjToSameFunction<K> editor)
      Sets the editor that can alter the sub-keys in an Iterable key when they are being used for equality and hashing. This does not apply any changes to the keys in this data structure; it only affects how they are hashed or compared. An editor could be a lambda or method reference; the only real requirement is that it takes a K sub-key and returns a K sub-key. The default filter returns the sub-key it is passed without changes. If the editor changes, that invalidates anything previously entered into this, so before changing the editor this clears the entire data structure, removing all existing entries.
      Parameters:
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      Returns:
      this, for chaining
    • setModifiers

      public FilteredIterableMap<K,I,V> setModifiers(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor)
      Equivalent to calling myMap.setFilter(filter).setEditor(editor), but only clears the data structure once.
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      Returns:
      this, for chaining
      See Also:
    • hashHelper

      protected int hashHelper(I s)
    • 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<I extends Iterable<K>,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

      public boolean equate(Object left, Object right)
      Compares two objects for equality by the rules this filtered data structure uses for keys. This will return true if the arguments are reference-equivalent or both null. Otherwise, it requires that both are Iterables and compares them using the filter and editor of this object.
      Overrides:
      equate in class ObjectObjectMap<I extends Iterable<K>,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 equivalent according to the rules this filtered type uses
    • hashCode

      public int hashCode()
      Specified by:
      hashCode in interface Map<K,I extends Iterable<K>>
      Overrides:
      hashCode in class ObjectObjectMap<I extends Iterable<K>,V>
    • with

      public static <K, I extends Iterable<K>, V> FilteredIterableMap<K,I,V> with(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor)
      The same as with(ObjPredicate, ObjToSameFunction, Iterable, Object, Object...), except this takes no keys or values, and doesn't allocate an array from using varargs.
      Type Parameters:
      K - the type of sub-keys inside each Iterable key
      I - the type of keys, which must extend Iterable; inferred from key0
      V - the type of values, inferred from value0
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      Returns:
      a new FilteredIterableOrderedMap containing only the given key and value
      See Also:
    • with

      public static <K, I extends Iterable<K>, V> FilteredIterableMap<K,I,V> with(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, I key, V value)
      The same as with(ObjPredicate, ObjToSameFunction, Iterable, Object, Object...), except this only takes one key-value pair, and doesn't allocate an array from using varargs.
      Type Parameters:
      K - the type of sub-keys inside each Iterable key
      I - the type of keys, which must extend Iterable; inferred from key0
      V - the type of values, inferred from value0
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      key - the only key that will be present in the returned map
      value - the only value that will be present in the returned map
      Returns:
      a new FilteredIterableOrderedMap containing only the given key and value
      See Also:
    • with

      public static <K, I extends Iterable<K>, V> FilteredIterableMap<K,I,V> with(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, I key0, V value0, I key1, V value1)
      The same as with(ObjPredicate, ObjToSameFunction, Iterable, Object, Object...), except this only takes the given key-value pairs, and doesn't allocate an array from using varargs.
      Type Parameters:
      K - the type of sub-keys inside each Iterable key
      I - the type of keys, which must extend Iterable; inferred from key0
      V - the type of values, inferred from value0
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      key0 - a key that will be present in the returned map
      value0 - a value that will be present in the returned map
      key1 - a key that will be present in the returned map
      value1 - a value that will be present in the returned map
      Returns:
      a new FilteredIterableOrderedMap containing only the given keys and values
      See Also:
    • with

      public static <K, I extends Iterable<K>, V> FilteredIterableMap<K,I,V> with(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, I key0, V value0, I key1, V value1, I key2, V value2)
      The same as with(ObjPredicate, ObjToSameFunction, Iterable, Object, Object...), except this only takes the given key-value pairs, and doesn't allocate an array from using varargs.
      Type Parameters:
      K - the type of sub-keys inside each Iterable key
      I - the type of keys, which must extend Iterable; inferred from key0
      V - the type of values, inferred from value0
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      key0 - a key that will be present in the returned map
      value0 - a value that will be present in the returned map
      key1 - a key that will be present in the returned map
      value1 - a value that will be present in the returned map
      key2 - a key that will be present in the returned map
      value2 - a value that will be present in the returned map
      Returns:
      a new FilteredIterableOrderedMap containing only the given keys and values
      See Also:
    • with

      public static <K, I extends Iterable<K>, V> FilteredIterableMap<K,I,V> with(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, I key0, V value0, I key1, V value1, I key2, V value2, I key3, V value3)
      The same as with(ObjPredicate, ObjToSameFunction, Iterable, Object, Object...), except this only takes the given key-value pairs, and doesn't allocate an array from using varargs.
      Type Parameters:
      K - the type of sub-keys inside each Iterable key
      I - the type of keys, which must extend Iterable; inferred from key0
      V - the type of values, inferred from value0
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      key0 - a key that will be present in the returned map
      value0 - a value that will be present in the returned map
      key1 - a key that will be present in the returned map
      value1 - a value that will be present in the returned map
      key2 - a key that will be present in the returned map
      value2 - a value that will be present in the returned map
      key3 - a key that will be present in the returned map
      value3 - a value that will be present in the returned map
      Returns:
      a new FilteredIterableOrderedMap containing only the given keys and values
      See Also:
    • with

      public static <K, I extends Iterable<K>, V> FilteredIterableMap<K,I,V> with(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, I key0, V value0, Object... rest)
      Constructs a map given a filter, an editor, and then 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 FilteredIterableMap(ObjPredicate, ObjToSameFunction, Iterable[], 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 I as their type or values that don't have V as their type have that entry skipped.
      Type Parameters:
      K - the type of sub-keys inside each Iterable key
      I - the type of keys, which must extend Iterable; inferred from key0
      V - the type of values, inferred from value0
      Parameters:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      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 I, V, I, V... elements
      Returns:
      a new map containing the given keys and values
    • parse

      public static <K, I extends Iterable<K>, V> FilteredIterableMap<K,I,V> parse(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, String str, String entrySeparator, String keyValueSeparator, PartialParser<I> keyParser, PartialParser<V> valueParser)
      Creates a new map by parsing all of str with the given PartialParser for keys and 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:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      str - a String containing parseable text
      entrySeparator - the String separating every key-value pair
      keyValueSeparator - the String separating every key from its corresponding value
      keyParser - a PartialParser that returns a I Iterable from a section of str
      valueParser - a PartialParser that returns a V value from a section of str
    • parse

      public static <K, I extends Iterable<K>, V> FilteredIterableMap<K,I,V> parse(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, String str, String entrySeparator, String keyValueSeparator, PartialParser<I> keyParser, 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 keys and 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:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      str - a String containing parseable text
      entrySeparator - the String separating every key-value pair
      keyValueSeparator - the String separating every key from its corresponding value
      keyParser - a PartialParser that returns a I Iterable from a section of str
      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 <K, I extends Iterable<K>, V> FilteredIterableMap<K,I,V> parse(com.github.tommyettinger.function.ObjPredicate<K> filter, com.github.tommyettinger.function.ObjToSameFunction<K> editor, String str, String entrySeparator, String keyValueSeparator, PartialParser<I> keyParser, PartialParser<V> valueParser, int offset, int length)
      Creates a new map by parsing the given subrange of str with the given PartialParser for keys and 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:
      filter - a ObjPredicate that should return true iff a sub-key should be considered for equality/hashing
      editor - a ObjToSameFunction that will be given a sub-key and may return a potentially different K sub-key
      str - a String containing parseable text
      entrySeparator - the String separating every key-value pair
      keyValueSeparator - the String separating every key from its corresponding value
      keyParser - a PartialParser that returns a I Iterable from a section of str
      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