Class CompactMap<K,V>

java.lang.Object
com.cedarsoftware.util.CompactMap<K,V>
All Implemented Interfaces:
Map<K,V>
Direct Known Subclasses:
CompactCIHashMap, CompactCILinkedMap, CompactLinkedMap

public class CompactMap<K,V> extends Object implements Map<K,V>
Many developers do not realize than they may have thousands or hundreds of thousands of Maps in memory, often representing small JSON objects. These maps (often HashMaps) usually have a table of 16/32/64... elements in them, with many empty elements. HashMap doubles it's internal storage each time it expands, so often these Maps have fewer than 50% of these arrays filled.

CompactMap is a Map that strives to reduce memory at all costs while retaining speed that is close to HashMap's speed. It does this by using only one (1) member variable (of type Object) and changing it as the Map grows. It goes from single value, to a single MapEntry, to an Object[], and finally it uses a Map (user defined). CompactMap is especially small when 0 and 1 entries are stored in it. When size() is from `2` to compactSize(), then entries are stored internally in single Object[]. If the size() is > compactSize() then the entries are stored in a regular `Map`.

     Methods you may want to override:

     // If this key is used and only 1 element then only the value is stored
     protected K getSingleValueKey() { return "someKey"; }

     // Map you would like it to use when size() > compactSize().  HashMap is default
     protected abstract Map<K, V> getNewMap();

     // If you want case insensitivity, return true and return new CaseInsensitiveMap or TreeMap(String.CASE_INSENSITIVE_PRDER) from getNewMap()
     protected boolean isCaseInsensitive() { return false; }

     // When size() > than this amount, the Map returned from getNewMap() is used to store elements.
     protected int compactSize() { return 80; }

 
**Empty** This class only has one (1) member variable of type `Object`. If there are no entries in it, then the value of that member variable takes on a pointer (points to sentinel value.)

**One entry** If the entry has a key that matches the value returned from `getSingleValueKey()` then there is no key stored and the internal single member points to the value only.

If the single entry's key does not match the value returned from `getSingleValueKey()` then the internal field points to an internal `Class` `CompactMapEntry` which contains the key and the value (nothing else). Again, all APIs still operate the same.

**Two thru compactSize() entries** In this case, the single member variable points to a single Object[] that contains all the keys and values. The keys are in the even positions, the values are in the odd positions (1 up from the key). [0] = key, [1] = value, [2] = next key, [3] = next value, and so on. The Object[] is dynamically expanded until size() > compactSize(). In addition, it is dynamically shrunk until the size becomes 1, and then it switches to a single Map Entry or a single value.

**size() greater than compactSize()** In this case, the single member variable points to a `Map` instance (supplied by `getNewMap()` API that user supplied.) This allows `CompactMap` to work with nearly all `Map` types.

This Map supports null for the key and values, as long as the Map returned by getNewMap() supports null keys-values.
Author:
John DeRegnaucourt ([email protected])
Copyright (c) Cedar Software LLC

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
  • Constructor Details

    • CompactMap

      public CompactMap()
    • CompactMap

      public CompactMap(Map<K,V> other)
  • Method Details

    • size

      public int size()
      Specified by:
      size in interface Map<K,V>
    • isEmpty

      public boolean isEmpty()
      Specified by:
      isEmpty in interface Map<K,V>
    • containsKey

      public boolean containsKey(Object key)
      Specified by:
      containsKey in interface Map<K,V>
    • containsValue

      public boolean containsValue(Object value)
      Specified by:
      containsValue in interface Map<K,V>
    • get

      public V get(Object key)
      Specified by:
      get in interface Map<K,V>
    • put

      public V put(K key, V value)
      Specified by:
      put in interface Map<K,V>
    • remove

      public V remove(Object key)
      Specified by:
      remove in interface Map<K,V>
    • putAll

      public void putAll(Map<? extends K,? extends V> map)
      Specified by:
      putAll in interface Map<K,V>
    • clear

      public void clear()
      Specified by:
      clear in interface Map<K,V>
    • hashCode

      public int hashCode()
      Specified by:
      hashCode in interface Map<K,V>
      Overrides:
      hashCode in class Object
    • equals

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

      public String toString()
      Overrides:
      toString in class Object
    • keySet

      public Set<K> keySet()
      Specified by:
      keySet in interface Map<K,V>
    • values

      public Collection<V> values()
      Specified by:
      values in interface Map<K,V>
    • entrySet

      public Set<Map.Entry<K,V>> entrySet()
      Specified by:
      entrySet in interface Map<K,V>
    • minus

      public Map<K,V> minus(Object removeMe)
    • plus

      public Map<K,V> plus(Object right)
    • getLogicalValueType

      protected CompactMap.LogicalValueType getLogicalValueType()
    • computeKeyHashCode

      protected int computeKeyHashCode(Object key)
    • computeValueHashCode

      protected int computeValueHashCode(Object value)
    • getSingleValueKey

      protected K getSingleValueKey()
      Returns:
      String key name when there is only one entry in the Map.
    • getNewMap

      protected Map<K,V> getNewMap()
      Returns:
      new empty Map instance to use when size() becomes > compactSize().
    • getNewMap

      protected Map<K,V> getNewMap(int size)
    • isCaseInsensitive

      protected boolean isCaseInsensitive()
    • compactSize

      protected int compactSize()
    • useCopyIterator

      protected boolean useCopyIterator()