Mega Code Archive

 
Categories / Java / Collections Data Structure
 

A java util Map interface which can only hold a single object

/*  * $Id: MicroMap.java 458489 2006-01-04 09:28:14Z ivaynberg $ $Revision:  * 1.4 $ $Date: 2006-01-04 10:28:14 +0100 (Wed, 04 Jan 2006) $  *   *   * 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.  */ import java.io.Serializable; import java.util.AbstractList; import java.util.AbstractSet; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.Set; /**  * An implementation of the java.util.Map interface which can only hold a single  * object. This is particularly useful to control memory usage in Wicket because  * many containers hold only a single component.  *   * @author Jonathan Locke  */ public final class MicroMap implements Map, Serializable {   private static final long serialVersionUID = 1L;   /** The maximum number of entries this map supports. */   public static final int MAX_ENTRIES = 1;   /** The one and only key in this tiny map */   private Object key;   /** The value for the only key in this tiny map */   private Object value;   /**    * Constructor    */   public MicroMap()   {   }   /**    * Constructs map with a single key and value pair.    *     * @param key    *            The key    * @param value    *            The value    */   public MicroMap(final Object key, final Object value)   {     put(key, value);   }   /**    * @return True if this MicroMap is full    */   public boolean isFull()   {     return size() == MAX_ENTRIES;   }   /**    * @see java.util.Map#size()    */   public int size()   {     return (key != null) ? 1 : 0;   }   /**    * @see java.util.Map#isEmpty()    */   public boolean isEmpty()   {     return size() == 0;   }   /**    * @see java.util.Map#containsKey(java.lang.Object)    */   public boolean containsKey(final Object key)   {     return key.equals(this.key);   }   /**    * @see java.util.Map#containsValue(java.lang.Object)    */   public boolean containsValue(final Object value)   {     return value.equals(this.value);   }   /**    * @see java.util.Map#get(java.lang.Object)    */   public Object get(final Object key)   {     if (key.equals(this.key))     {       return value;     }     return null;   }   /**    * @see java.util.Map#put(java.lang.Object, java.lang.Object)    */   public Object put(final Object key, final Object value)   {     // Replace?     if (key.equals(this.key))     {       final Object oldValue = this.value;       this.value = value;       return oldValue;     }     else     {       // Is there room for a new entry?       if (size() < MAX_ENTRIES)       {         // Store         this.key = key;         this.value = value;         return null;       }       else       {         throw new IllegalStateException("Map full");       }     }   }   /**    * @see java.util.Map#remove(java.lang.Object)    */   public Object remove(final Object key)   {     if (key.equals(this.key))     {       final Object oldValue = this.value;       this.key = null;       this.value = null;       return oldValue;     }     return null;   }   /**    * @see java.util.Map#putAll(java.util.Map)    */   public void putAll(final Map map)   {     if (map.size() <= MAX_ENTRIES)     {       final Map.Entry e = (Map.Entry)map.entrySet().iterator().next();       put(e.getKey(), e.getValue());     }     else     {       throw new IllegalStateException("Map full.  Cannot add " + map.size() + " entries");     }   }   /**    * @see java.util.Map#clear()    */   public void clear()   {     key = null;     value = null;   }   /**    * @see java.util.Map#keySet()    */   public Set keySet()   {     return new AbstractSet()     {       public Iterator iterator()       {         return new Iterator()         {           public boolean hasNext()           {             return index < MicroMap.this.size();           }           public Object next()           {             index++;             return key;           }           public void remove()           {             MicroMap.this.clear();           }           int index;         };       }       public int size()       {         return MicroMap.this.size();       }     };   }   /**    * @see java.util.Map#values()    */   public Collection values()   {     return new AbstractList()     {       public Object get(final int index)       {         return value;       }       public int size()       {         return MicroMap.this.size();       }     };   }   /**    * @see java.util.Map#entrySet()    */   public Set entrySet()   {     return new AbstractSet()     {       public Iterator iterator()       {         return new Iterator()         {           public boolean hasNext()           {             return index < MicroMap.this.size();           }           public Object next()           {             index++;             return new Map.Entry()             {               public Object getKey()               {                 return key;               }               public Object getValue()               {                 return value;               }               public Object setValue(final Object value)               {                 final Object oldValue = MicroMap.this.value;                 MicroMap.this.value = value;                 return oldValue;               }             };           }           public void remove()           {             clear();           }           int index = 0;         };       }       public int size()       {         return MicroMap.this.size();       }     };   } }