001package com.hfg.util.collection;
002
003import java.util.HashMap;
004import java.util.Map;
005
006
007//------------------------------------------------------------------------------
008/**
009 Simple implementation of a bi-directional map.
010 <div>
011 @author J. Alex Taylor, hairyfatguy.com
012 </div>
013 */
014//------------------------------------------------------------------------------
015// com.hfg Library
016//
017// This library is free software; you can redistribute it and/or
018// modify it under the terms of the GNU Lesser General Public
019// License as published by the Free Software Foundation; either
020// version 2.1 of the License, or (at your option) any later version.
021//
022// This library is distributed in the hope that it will be useful,
023// but WITHOUT ANY WARRANTY; without even the implied warranty of
024// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
025// Lesser General Public License for more details.
026//
027// You should have received a copy of the GNU Lesser General Public
028// License along with this library; if not, write to the Free Software
029// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
030//
031// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
032// jataylor@hairyfatguy.com
033//------------------------------------------------------------------------------
034
035public class BiHashMap<K, V> extends HashMap<K, V> implements BiMap<K, V>
036{
037   private Map<V, K> mReverseMap;
038
039   //##########################################################################
040   // CONSTRUCTORS
041   //##########################################################################
042
043   //--------------------------------------------------------------------------
044   public BiHashMap()
045   {
046      super();
047      init(null);
048   }
049
050   //--------------------------------------------------------------------------
051   public BiHashMap(int inInitialSize)
052   {
053      super(inInitialSize);
054      init(inInitialSize);
055   }
056
057   //--------------------------------------------------------------------------
058   private void init(Integer inInitialSize)
059   {
060      if (inInitialSize != null)
061      {
062         mReverseMap = new HashMap<>(inInitialSize);
063      }
064      else
065      {
066         mReverseMap = new HashMap<>();
067      }
068   }
069
070   //##########################################################################
071   // PUBLIC METHODS
072   //##########################################################################
073
074   //--------------------------------------------------------------------------
075   /**
076    Performs a reverse lookup on the Map.
077    * @param inValue the value to use
078    * @return the key associated with the value
079    */
080   public K getKey(V inValue)
081   {
082      return mReverseMap.get(inValue);
083   }
084
085   //--------------------------------------------------------------------------
086   @Override
087   public V put(K inKey, V inValue)
088   {
089      mReverseMap.put(inValue, inKey);
090      return super.put(inKey, inValue);
091   }
092
093   //--------------------------------------------------------------------------
094   @Override
095   public void putAll(Map<? extends K, ? extends V> inValues)
096   {
097      if (CollectionUtil.hasValues(inValues))
098      {
099         for (K key : inValues.keySet())
100         {
101            mReverseMap.put(inValues.get(key), key);
102         }
103      }
104
105      super.putAll(inValues);
106   }
107
108   //--------------------------------------------------------------------------
109   @Override
110   public V putIfAbsent(K inKey, V inValue)
111   {
112      mReverseMap.putIfAbsent(inValue, inKey);
113      return super.putIfAbsent(inKey, inValue);
114   }
115
116   //--------------------------------------------------------------------------
117   @Override
118   public void clear()
119   {
120      mReverseMap.clear();
121      super.clear();
122   }
123
124   //--------------------------------------------------------------------------
125   @Override
126   public V remove(Object inKey)
127   {
128      mReverseMap.remove(get(inKey));
129      return super.remove(inKey);
130   }
131
132   //--------------------------------------------------------------------------
133   @Override
134   public V replace(K inKey, V inValue)
135   {
136      mReverseMap.remove(get(inKey));
137      mReverseMap.put(inValue, inKey);
138      return super.replace(inKey, inValue);
139   }
140
141   //--------------------------------------------------------------------------
142   @Override
143   public boolean containsValue(Object inValue)
144   {
145      return mReverseMap.containsKey(inValue);
146   }
147
148}