Class ArrayMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>

java.lang.Object
java.util.AbstractMap<K,V>
org.plumelib.util.ArrayMap<K,V>
Type Parameters:
K - the type of keys maintained by this map
V - the type of mapped values
All Implemented Interfaces:
Map<K,V>

public class ArrayMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object> extends AbstractMap<K,V>
A map backed by two arrays. It permits null keys and values, and its iterator has deterministic ordering.

Compared to a HashMap or LinkedHashMap: For very small maps, this uses much less space, has comparable performance, and (like a LinkedHashMap) is deterministic, with elements returned in the order their keys were inserted. For large maps, this is significantly less performant than other map implementations.

Compared to a TreeMap: This uses somewhat less space, and it does not require defining a comparator. This isn't sorted but does have deterministic ordering. For large maps, this is significantly less performant than other map implementations.

A number of other ArrayMap implementations exist, including

  • android.util.ArrayMap
  • com.google.api.client.util.ArrayMap
  • it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
  • oracle.dss.util.ArrayMap
  • org.apache.myfaces.trinidad.util.ArrayMap
All of those use the Apache License, version 2.0, whereas this implementation is licensed under the more libral MIT License. In addition, some of those implementations forbid nulls or nondeterministically reorder the contents, and others don't specify their behavior regarding nulls and ordering.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    (package private) class 
    An iterator over the ArrayMap.
    (package private) final class 
    An entrySet() entry.
    (package private) final class 
    An iterator over the entries.
    (package private) final class 
    Represents a view of the entries.
    (package private) final class 
    An iterator over the keys.
    (package private) final class 
    Represents a view of the keys.
    (package private) final class 
    An iterator over the values.
    (package private) final class 
    Represents a view of the values.

    Nested classes/interfaces inherited from class java.util.AbstractMap

    AbstractMap.SimpleEntry<K extends Object,V extends Object>, AbstractMap.SimpleImmutableEntry<K extends Object,V extends Object>
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    (package private) @MonotonicNonNull Set<Map.Entry<@KeyFor("this") K,V>>
    The view of the entries.
    private @Nullable K @SameLen("values") []
    The keys.
    (package private) @MonotonicNonNull Set<@KeyFor("this") K>
    A view of the keys.
    private @org.checkerframework.checker.index.qual.NonNegative,@org.checkerframework.checker.index.qual.LessThan({"keys.length + 1"}),@org.checkerframework.checker.index.qual.IndexOrHigh({"keys", "values"}) int
    The number of used mappings in the representation of this.
    (package private) int
    The number of times this map's size has been modified by adding or removing an element (changing the value associated with a key does not count as a change).
    private @Nullable V @SameLen("keys") []
    The values.
    (package private) @MonotonicNonNull Collection<V>
    The view of the values.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
     
    Constructs an empty ArrayMap with the default initial capacity.
     
    ArrayMap(int initialCapacity)
    Constructs an empty ArrayMap with the specified initial capacity.
     
    ArrayMap(Map<? extends K,? extends V> m)
    Constructs a new ArrayMap with the same mappings as the given Map.
    private
    ArrayMap(K @SameLen("values") [] keys, V @SameLen("keys") [] values, @org.checkerframework.checker.index.qual.LTEqLengthOf({"keys", "values"}) int size)
    Private constructor.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
     
    Returns a copy of this.
    @PolyNull V
    compute(K key, BiFunction<? super K,? super @Nullable V,? extends @PolyNull V> remappingFunction)
     
    @PolyNull V
    computeIfAbsent(K key, Function<? super K,? extends @PolyNull V> mappingFunction)
     
    @PolyNull V
    computeIfPresent(K key, BiFunction<? super K,? super V,? extends @PolyNull V> remappingFunction)
     
    private boolean
    containsEntry(@GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value)
    Returns true if this map contains the given mapping.
    boolean
    containsKey(@GuardSatisfied @Nullable @UnknownSignedness Object key)
     
    boolean
    containsValue(@GuardSatisfied @Nullable @UnknownSignedness Object value)
     
    Set<Map.Entry<@KeyFor("this") K,V>>
     
    void
    forEach(BiConsumer<? super K,? super V> action)
     
    @Nullable V
    get(@GuardSatisfied @Nullable @UnknownSignedness Object key)
     
    getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object key, V defaultValue)
     
    private @Nullable V
    getOrNull(@org.checkerframework.checker.index.qual.GTENegativeOne int index)
    Returns the value at the given index, or null if the index is -1.
    private void
    Increases the capacity of the arrays.
    private int
    indexOfKey(@GuardSatisfied @Nullable @UnknownSignedness Object key)
    Returns the index of the given key, or -1 if it does not appear.
    private int
    indexOfValue(@GuardSatisfied @Nullable @UnknownSignedness Object value)
    Returns the index of the given value, or -1 if it does not appear.
    boolean
     
    Set<@KeyFor("this") K>
     
    @PolyNull V
    merge(K key, @NonNull V value, BiFunction<? super V,? super V,? extends @PolyNull V> remappingFunction)
     
    static <K, V> Map<K,V>
    newArrayMapOrHashMap(int capacity)
    Returns a new ArrayMap or HashMap with the given capacity.
    static <K, V> Map<K,V>
    Returns a new ArrayMap or HashMap with the given elements.
    static <K, V> Map<K,V>
    Returns a new ArrayMap or LinkedHashMap with the given capacity.
    static <K, V> Map<K,V>
    Returns a new ArrayMap or LinkedHashMap with the given elements.
    private void
    put(@org.checkerframework.checker.index.qual.GTENegativeOne int index, K key, V value)
    Adds the (key, value) mapping to this.
    @Nullable V
    put(K key, V value)
     
    void
    putAll(Map<? extends K,? extends V> m)
     
    @Nullable V
    putIfAbsent(K key, V value)
     
    @Nullable V
    remove(@GuardSatisfied @Nullable @UnknownSignedness Object key)
     
    boolean
    remove(@GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value)
     
    private boolean
    removeIndex(@org.checkerframework.checker.index.qual.GTENegativeOne int index)
    Remove the mapping at the given index.
    @Nullable V
    replace(K key, V value)
     
    boolean
    replace(K key, V oldValue, V newValue)
     
    void
    replaceAll(BiFunction<? super K,? super V,? extends V> function)
     
    (package private) String
    Returns the internal representation, printed.
    @org.checkerframework.checker.index.qual.NonNegative int
     
     

    Methods inherited from class java.util.AbstractMap

    equals, hashCode, toString

    Methods inherited from class java.lang.Object

    finalize, getClass, notify, notifyAll, wait, wait, wait
  • Field Details

    • keys

      private @Nullable K extends @UnknownSignedness Object @SameLen("values") [] keys
      The keys. Null if capacity=0.
    • values

      private @Nullable V extends @UnknownSignedness Object @SameLen("keys") [] values
      The values. Null if capacity=0.
    • size

      private @org.checkerframework.checker.index.qual.NonNegative,@org.checkerframework.checker.index.qual.LessThan({"keys.length + 1"}),@org.checkerframework.checker.index.qual.IndexOrHigh({"keys", "values"}) int size
      The number of used mappings in the representation of this.
    • sizeModificationCount

      transient int sizeModificationCount
      The number of times this map's size has been modified by adding or removing an element (changing the value associated with a key does not count as a change). This field is used to make view iterators fail-fast.
    • keySet

      @MonotonicNonNull Set<@KeyFor("this") K extends @UnknownSignedness Object> keySet
      A view of the keys.
    • valuesCollection

      @MonotonicNonNull Collection<V extends @UnknownSignedness Object> valuesCollection
      The view of the values.
    • entrySet

      @MonotonicNonNull Set<Map.Entry<@KeyFor("this") K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>> entrySet
      The view of the entries.
  • Constructor Details

    • ArrayMap

      @SideEffectFree public ArrayMap(int initialCapacity)
      Constructs an empty ArrayMap with the specified initial capacity.
      Parameters:
      initialCapacity - the initial capacity
      Throws:
      IllegalArgumentException - if the initial capacity is negative
    • ArrayMap

      @SideEffectFree public ArrayMap()
      Constructs an empty ArrayMap with the default initial capacity.
    • ArrayMap

      @SideEffectFree private ArrayMap(K @SameLen("values") [] keys, V @SameLen("keys") [] values, @org.checkerframework.checker.index.qual.LTEqLengthOf({"keys", "values"}) int size)
      Private constructor. Installs the given objects in this as its representation, without making defensive copies.
      Parameters:
      keys - the keys
      values - the values
      size - the number of used items in the arrays; may be less than their lengths
    • ArrayMap

      @SideEffectFree public ArrayMap(Map<? extends K,? extends V> m)
      Constructs a new ArrayMap with the same mappings as the given Map.
      Parameters:
      m - the map whose mappings are to be placed in this map
      Throws:
      NullPointerException - if the given map is null
  • Method Details

    • newArrayMapOrHashMap

      public static <K, V> Map<K,V> newArrayMapOrHashMap(int capacity)
      Returns a new ArrayMap or HashMap with the given capacity. Uses an ArrayMap if the capacity is small, and a HashMap otherwise.
      Type Parameters:
      K - the type of the keys
      V - the type of the values
      Parameters:
      capacity - the expected maximum number of elements in the set
      Returns:
      a new ArrayMap or HashMap with the given capacity
    • newArrayMapOrHashMap

      public static <K, V> Map<K,V> newArrayMapOrHashMap(Map<K,V> m)
      Returns a new ArrayMap or HashMap with the given elements. Uses an ArrayMap if the capacity is small, and a HashMap otherwise.
      Type Parameters:
      K - the type of the keys
      V - the type of the values
      Parameters:
      m - the elements to put in the returned set
      Returns:
      a new ArrayMap or HashMap with the given elements
    • newArrayMapOrLinkedHashMap

      public static <K, V> Map<K,V> newArrayMapOrLinkedHashMap(int capacity)
      Returns a new ArrayMap or LinkedHashMap with the given capacity. Uses an ArrayMap if the capacity is small, and a LinkedHashMap otherwise.
      Type Parameters:
      K - the type of the keys
      V - the type of the values
      Parameters:
      capacity - the expected maximum number of elements in the set
      Returns:
      a new ArrayMap or LinkedHashMap with the given capacity
    • newArrayMapOrLinkedHashMap

      public static <K, V> Map<K,V> newArrayMapOrLinkedHashMap(Map<K,V> m)
      Returns a new ArrayMap or LinkedHashMap with the given elements. Uses an ArrayMap if the capacity is small, and a LinkedHashMap otherwise.
      Type Parameters:
      K - the type of the keys
      V - the type of the values
      Parameters:
      m - the elements to put in the returned set
      Returns:
      a new ArrayMap or LinkedHashMap with the given elements
    • put

      @EnsuresKeyFor(value="#2", map="this") private void put(@org.checkerframework.checker.index.qual.GTENegativeOne int index, K key, V value)
      Adds the (key, value) mapping to this.
      Parameters:
      index - the index of key in keys. If -1, add a new mapping. Otherwise, replace the mapping at index.
      key - the key
      value - the value
    • grow

      private void grow()
      Increases the capacity of the arrays.
    • removeIndex

      private boolean removeIndex(@org.checkerframework.checker.index.qual.GTENegativeOne int index)
      Remove the mapping at the given index. Does nothing if index is -1.
      Parameters:
      index - the index of the mapping to remove
      Returns:
      true if this map was modified
    • size

      @Pure public @org.checkerframework.checker.index.qual.NonNegative int size()
      Specified by:
      size in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      size in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • isEmpty

      @Pure public boolean isEmpty()
      Specified by:
      isEmpty in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      isEmpty in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • indexOfKey

      @Pure private int indexOfKey(@GuardSatisfied @Nullable @UnknownSignedness Object key)
      Returns the index of the given key, or -1 if it does not appear. Uses Objects.equals for comparison.
      Parameters:
      key - a key to find
      Returns:
      the index of the given key, or -1 if it does not appear
    • indexOfValue

      @Pure private int indexOfValue(@GuardSatisfied @Nullable @UnknownSignedness Object value)
      Returns the index of the given value, or -1 if it does not appear. Uses Objects.equals for comparison.
      Parameters:
      value - a value to find
      Returns:
      the index of the given value, or -1 if it does not appear
    • containsKey

      @Pure public boolean containsKey(@GuardSatisfied @Nullable @UnknownSignedness Object key)
      Specified by:
      containsKey in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      containsKey in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • containsValue

      @Pure public boolean containsValue(@GuardSatisfied @Nullable @UnknownSignedness Object value)
      Specified by:
      containsValue in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      containsValue in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • containsEntry

      @Pure private boolean containsEntry(@GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value)
      Returns true if this map contains the given mapping.
      Parameters:
      key - the key
      value - the value
      Returns:
      true if this map contains the given mapping
    • get

      @Pure public @Nullable V get(@GuardSatisfied @Nullable @UnknownSignedness Object key)
      Specified by:
      get in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      get in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • getOrNull

      @Pure private @Nullable V getOrNull(@org.checkerframework.checker.index.qual.GTENegativeOne int index)
      Returns the value at the given index, or null if the index is -1.
      Parameters:
      index - the index
      Returns:
      the value at the given index, or null if the index is -1
    • put

      public @Nullable V put(K key, V value)
      Specified by:
      put in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      put in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • remove

      public @Nullable V remove(@GuardSatisfied @Nullable @UnknownSignedness Object key)
      Specified by:
      remove in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      remove in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • putAll

      public void putAll(Map<? extends K,? extends V> m)
      Specified by:
      putAll in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      putAll in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • clear

      public void clear()
      Specified by:
      clear in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      clear in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • keySet

      @Pure public Set<@KeyFor("this") K> keySet()
      Specified by:
      keySet in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      keySet in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • values

      @Pure public Collection<V> values()
      Specified by:
      values in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Overrides:
      values in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • entrySet

      @Pure public Set<Map.Entry<@KeyFor("this") K,V>> entrySet()
      Specified by:
      entrySet in interface Map<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Specified by:
      entrySet in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
    • getOrDefault

      @SideEffectFree public V getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object key, V defaultValue)
    • forEach

      public void forEach(BiConsumer<? super K,? super V> action)
    • replaceAll

      public void replaceAll(BiFunction<? super K,? super V,? extends V> function)
    • putIfAbsent

      public @Nullable V putIfAbsent(K key, V value)
    • remove

      public boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value)
    • replace

      public boolean replace(K key, V oldValue, V newValue)
    • replace

      public @Nullable V replace(K key, V value)
    • computeIfAbsent

      public @PolyNull V computeIfAbsent(K key, Function<? super K,? extends @PolyNull V> mappingFunction)
    • computeIfPresent

      public @PolyNull V computeIfPresent(K key, BiFunction<? super K,? super V,? extends @PolyNull V> remappingFunction)
    • compute

      public @PolyNull V compute(K key, BiFunction<? super K,? super @Nullable V,? extends @PolyNull V> remappingFunction)
    • merge

      public @PolyNull V merge(K key, @NonNull V value, BiFunction<? super V,? super V,? extends @PolyNull V> remappingFunction)
    • clone

      @SideEffectFree public ArrayMap<K,V> clone()
      Returns a copy of this.
      Overrides:
      clone in class AbstractMap<K extends @UnknownSignedness Object,V extends @UnknownSignedness Object>
      Returns:
      a copy of this
    • repr

      @SideEffectFree String repr()
      Returns the internal representation, printed.
      Returns:
      the internal representation, printed