/////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2002, Eric D. Friedman All Rights Reserved. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /////////////////////////////////////////////////////////////////////////////// package gnu.trove.decorator; import gnu.trove.TDoubleIntHashMap; import gnu.trove.TDoubleIntIterator; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.Collection; import java.util.Iterator; import java.util.Map.Entry; import java.util.Map; import java.util.Set; /** * Wrapper class to make a TDoubleIntHashMap conform to the java.util.Map API. * This class simply decorates an underlying TDoubleIntHashMap and translates the Object-based * APIs into their Trove primitive analogs. * *

* Note that wrapping and unwrapping primitive values is extremely inefficient. If * possible, users of this class should override the appropriate methods in this class * and use a table of canonical values. *

* * Created: Mon Sep 23 22:07:40 PDT 2002 * * @author Eric D. Friedman * @version $Id: TDoubleIntHashMapDecorator.java,v 1.4 2004/03/18 15:30:34 ericdf Exp $ * @since trove 0.1.8 */ public class TDoubleIntHashMapDecorator extends AbstractMap implements Map, Cloneable { /** the wrapped primitive map */ protected TDoubleIntHashMap _map; /** * Creates a wrapper that decorates the specified primitive map. */ public TDoubleIntHashMapDecorator(TDoubleIntHashMap map) { super(); this._map = map; } /** * Clones the underlying trove collection and returns the clone wrapped in a new * decorator instance. This is a shallow clone except where primitives are * concerned. * * @return a copy of the receiver */ public Object clone() { try { TDoubleIntHashMapDecorator copy = (TDoubleIntHashMapDecorator) super.clone(); copy._map = (TDoubleIntHashMap)_map.clone(); return copy; } catch (CloneNotSupportedException e) { // assert(false); throw new InternalError(); // we are cloneable, so this does not happen } } /** * Inserts a key/value pair into the map. * * @param key an Object value * @param value an Object value * @return the previous value associated with key, * or Integer(0) if none was found. */ public Object put(Object key, Object value) { return wrapValue(_map.put(unwrapKey(key), unwrapValue(value))); } /** * Compares this map with another map for equality of their stored * entries. * * @param other an Object value * @return true if the maps are identical */ public boolean equals(Object other) { if (_map.equals(other)) { return true; // comparing two trove maps } else if (other instanceof Map) { Map that = (Map)other; if (that.size() != _map.size()) { return false; // different sizes, no need to compare } else { // now we have to do it the hard way Iterator it = that.entrySet().iterator(); for (int i = that.size(); i-- > 0;) { Map.Entry e = (Map.Entry)it.next(); Object key = e.getKey(); Object val = e.getValue(); if (key instanceof Double && val instanceof Integer) { double k = unwrapKey(key); int v = unwrapValue(val); if (_map.containsKey(k) && v == _map.get(k)) { // match, ok to continue } else { return false; // no match: we're done } } else { return false; // different type in other map } } return true; // all entries match } } else { return false; } } /** * Retrieves the value for key * * @param key an Object value * @return the value of key or null if no such mapping exists. */ public Object get(Object key) { double k = unwrapKey(key); int v = _map.get(k); // 0 may be a false positive since primitive maps // cannot return null, so we have to do an extra // check here. if (v == 0) { return _map.containsKey(k) ? wrapValue(v) : null; } else { return wrapValue(v); } } /** * Empties the map. */ public void clear() { this._map.clear(); } /** * Deletes a key/value pair from the map. * * @param key an Object value * @return the removed value, or Integer(0) if it was not found in the map */ public Object remove(Object key) { return wrapValue(_map.remove(unwrapKey(key))); } /** * Returns a Set view on the entries of the map. * * @return a Set value */ public Set entrySet() { return new AbstractSet() { public int size() { return _map.size(); } public boolean isEmpty() { return TDoubleIntHashMapDecorator.this.isEmpty(); } public boolean contains(Object o) { if (o instanceof Map.Entry) { Object k = ((Map.Entry)o).getKey(); Object v = ((Map.Entry)o).getValue(); return (TDoubleIntHashMapDecorator.this.containsKey(k) && TDoubleIntHashMapDecorator.this.get(k).equals(v)); } else { return false; } } public Iterator iterator() { return new Iterator() { private final TDoubleIntIterator it = _map.iterator(); public Object next() { it.advance(); final Object key = wrapKey(it.key()); final Object v = wrapValue(it.value()); return new Map.Entry() { private Object val = v; public boolean equals(Object o) { return ((o instanceof Map.Entry) && ((Map.Entry)o).getKey().equals(key) && ((Map.Entry)o).getValue().equals(val)); } public Object getKey() { return key; } public Object getValue() { return val; } public int hashCode() { return key.hashCode() + val.hashCode(); } public Object setValue(Object value) { val = value; return put(key, value); } }; } public boolean hasNext() { return it.hasNext(); } public void remove() { it.remove(); } }; } public boolean add(Object o) { throw new UnsupportedOperationException(); } public boolean remove(Object o) { throw new UnsupportedOperationException(); } public boolean addAll(Collection c) { throw new UnsupportedOperationException(); } public boolean retainAll(Collection c) { throw new UnsupportedOperationException(); } public boolean removeAll(Collection c) { throw new UnsupportedOperationException(); } public void clear() { TDoubleIntHashMapDecorator.this.clear(); } }; } /** * Checks for the presence of val in the values of the map. * * @param val an Object value * @return a boolean value */ public boolean containsValue(Object val) { return _map.containsValue(unwrapValue(val)); } /** * Checks for the present of key in the keys of the map. * * @param key an Object value * @return a boolean value */ public boolean containsKey(Object key) { return _map.containsKey(unwrapKey(key)); } /** * Returns the number of entries in the map. * @return the map's size. */ public int size() { return this._map.size(); } /** * Indicates whether map has any entries. * @return true if the map is empty */ public boolean isEmpty() { return (size() == 0); } /** * Copies the key/value mappings in map into this map. * Note that this will be a deep copy, as storage is by * primitive value. * * @param map a Map value */ public void putAll(Map map) { Iterator it = map.entrySet().iterator(); for (int i = map.size(); i-- > 0;) { Map.Entry e = (Map.Entry)it.next(); this.put(e.getKey(), e.getValue()); } } /** * Wraps a key * * @param a key in the underlying map * @return an Object representation of the key */ protected Double wrapKey(double k) { return new Double(k); } /** * Unwraps a key * * @param a wrapped key * @return an unwrapped representation of the key */ protected double unwrapKey(Object key) { return ((Double)key).doubleValue(); } /** * Wraps a value * * @param a value in the underlying map * @return an Object representation of the value */ protected Integer wrapValue(int k) { return new Integer(k); } /** * Unwraps a value * * @param a wrapped value * @return an unwrapped representation of the value */ protected int unwrapValue(Object value) { return ((Integer)value).intValue(); } } // TDoubleIntHashMapDecorator