http://git-wip-us.apache.org/repos/asf/commons-collections/blob/884baf0d/src/java/org/apache/commons/collections/bidimap/AbstractBidiMapDecorator.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/bidimap/AbstractBidiMapDecorator.java b/src/java/org/apache/commons/collections/bidimap/AbstractBidiMapDecorator.java index e725668..393cc4e 100644 --- a/src/java/org/apache/commons/collections/bidimap/AbstractBidiMapDecorator.java +++ b/src/java/org/apache/commons/collections/bidimap/AbstractBidiMapDecorator.java @@ -37,9 +37,8 @@ import org.apache.commons.collections.map.AbstractMapDecorator; * * @author Stephen Colebourne */ -public abstract class AbstractBidiMapDecorator - extends AbstractMapDecorator - implements BidiMap { +public abstract class AbstractBidiMapDecorator<K, V> extends AbstractMapDecorator<K, V> implements + BidiMap<K, V> { /** * Constructor that wraps (not copies). @@ -47,7 +46,7 @@ public abstract class AbstractBidiMapDecorator * @param map the map to decorate, must not be null * @throws IllegalArgumentException if the collection is null */ - protected AbstractBidiMapDecorator(BidiMap map) { + protected AbstractBidiMapDecorator(BidiMap<K, V> map) { super(map); } @@ -55,35 +54,25 @@ public abstract class AbstractBidiMapDecorator * Gets the map being decorated. * * @return the decorated map - * @deprecated use decorated() */ - protected BidiMap getBidiMap() { - return decorated(); - } - - /** - * Gets the map being decorated. - * - * @return the decorated map - */ - protected BidiMap decorated() { - return (BidiMap) super.decorated(); + protected BidiMap<K, V> decorated() { + return (BidiMap<K, V>) super.decorated(); } //----------------------------------------------------------------------- - public MapIterator mapIterator() { + public MapIterator<K, V> mapIterator() { return decorated().mapIterator(); } - public Object getKey(Object value) { + public K getKey(Object value) { return decorated().getKey(value); } - public Object removeValue(Object value) { + public K removeValue(Object value) { return decorated().removeValue(value); } - public BidiMap inverseBidiMap() { + public BidiMap<V, K> inverseBidiMap() { return decorated().inverseBidiMap(); }
http://git-wip-us.apache.org/repos/asf/commons-collections/blob/884baf0d/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java b/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java index a07ffcb..b69049d 100644 --- a/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java +++ b/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You 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. @@ -33,38 +33,46 @@ import org.apache.commons.collections.keyvalue.AbstractMapEntryDecorator; * <p> * An implementation can be written simply by implementing the * <code>createMap</code> method. - * + * * @see DualHashBidiMap * @see DualTreeBidiMap * @since Commons Collections 3.0 * @version $Id$ - * + * * @author Matthew Hawthorne * @author Stephen Colebourne */ -public abstract class AbstractDualBidiMap implements BidiMap { +public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> { /** - * Delegate map array. The first map contains standard entries, and the - * second contains inverses. + * Normal delegate map. */ - protected transient final Map[] maps = new Map[2]; + protected transient Map<K, V> normalMap; + + /** + * Reverse delegate map. + */ + protected transient Map<V, K> reverseMap; + /** * Inverse view of this map. */ - protected transient BidiMap inverseBidiMap = null; + protected transient BidiMap<V, K> inverseBidiMap = null; + /** * View of the keys. */ - protected transient Set keySet = null; + protected transient Set<K> keySet = null; + /** * View of the values. */ - protected transient Collection values = null; + protected transient Collection<V> values = null; + /** * View of the entries. */ - protected transient Set entrySet = null; + protected transient Set<Map.Entry<K, V>> entrySet = null; /** * Creates an empty map, initialised by <code>createMap</code>. @@ -86,18 +94,18 @@ public abstract class AbstractDualBidiMap implements BidiMap { * Neither map is validated, so nulls may be passed in. * If you choose to do this then the subclass constructor must populate * the <code>maps[]</code> instance variable itself. - * + * * @param normalMap the normal direction map * @param reverseMap the reverse direction map * @since Commons Collections 3.1 */ - protected AbstractDualBidiMap(Map normalMap, Map reverseMap) { + protected AbstractDualBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap) { super(); - maps[0] = normalMap; - maps[1] = reverseMap; + this.normalMap = normalMap; + this.reverseMap = reverseMap; } - /** + /** * Constructs a map that decorates the specified maps, * used by the subclass <code>createBidiMap</code> implementation. * @@ -105,90 +113,89 @@ public abstract class AbstractDualBidiMap implements BidiMap { * @param reverseMap the reverse direction map * @param inverseBidiMap the inverse BidiMap */ - protected AbstractDualBidiMap(Map normalMap, Map reverseMap, BidiMap inverseBidiMap) { + protected AbstractDualBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap, BidiMap<V, K> inverseBidiMap) { super(); - maps[0] = normalMap; - maps[1] = reverseMap; + this.normalMap = normalMap; + this.reverseMap = reverseMap; this.inverseBidiMap = inverseBidiMap; } /** * Creates a new instance of the subclass. - * + * * @param normalMap the normal direction map * @param reverseMap the reverse direction map * @param inverseMap this map, which is the inverse in the new map * @return the inverse map */ - protected abstract BidiMap createBidiMap(Map normalMap, Map reverseMap, BidiMap inverseMap); + protected abstract BidiMap<V, K> createBidiMap(Map<V, K> normalMap, Map<K, V> reverseMap, BidiMap<K, V> inverseMap); // Map delegation //----------------------------------------------------------------------- - public Object get(Object key) { - return maps[0].get(key); + public V get(Object key) { + return normalMap.get(key); } public int size() { - return maps[0].size(); + return normalMap.size(); } public boolean isEmpty() { - return maps[0].isEmpty(); + return normalMap.isEmpty(); } public boolean containsKey(Object key) { - return maps[0].containsKey(key); + return normalMap.containsKey(key); } public boolean equals(Object obj) { - return maps[0].equals(obj); + return normalMap.equals(obj); } public int hashCode() { - return maps[0].hashCode(); + return normalMap.hashCode(); } public String toString() { - return maps[0].toString(); + return normalMap.toString(); } // BidiMap changes //----------------------------------------------------------------------- - public Object put(Object key, Object value) { - if (maps[0].containsKey(key)) { - maps[1].remove(maps[0].get(key)); + public V put(K key, V value) { + if (normalMap.containsKey(key)) { + reverseMap.remove(normalMap.get(key)); } - if (maps[1].containsKey(value)) { - maps[0].remove(maps[1].get(value)); + if (reverseMap.containsKey(value)) { + normalMap.remove(reverseMap.get(value)); } - final Object obj = maps[0].put(key, value); - maps[1].put(value, key); + final V obj = normalMap.put(key, value); + reverseMap.put(value, key); return obj; } - - public void putAll(Map map) { - for (Iterator it = map.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); + + public void putAll(Map<? extends K, ? extends V> map) { + for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { put(entry.getKey(), entry.getValue()); } } - public Object remove(Object key) { - Object value = null; - if (maps[0].containsKey(key)) { - value = maps[0].remove(key); - maps[1].remove(value); + public V remove(Object key) { + V value = null; + if (normalMap.containsKey(key)) { + value = normalMap.remove(key); + reverseMap.remove(value); } return value; } public void clear() { - maps[0].clear(); - maps[1].clear(); + normalMap.clear(); + reverseMap.clear(); } public boolean containsValue(Object value) { - return maps[1].containsKey(value); + return reverseMap.containsKey(value); } // BidiMap @@ -201,45 +208,45 @@ public abstract class AbstractDualBidiMap implements BidiMap { * The setValue() methods only allow a new value to be set. * If the value being set is already in the map, an IllegalArgumentException * is thrown (as setValue cannot change the size of the map). - * + * * @return a map iterator */ - public MapIterator mapIterator() { - return new BidiMapIterator(this); + public MapIterator<K, V> mapIterator() { + return new BidiMapIterator<K, V>(this); } - - public Object getKey(Object value) { - return maps[1].get(value); + + public K getKey(Object value) { + return reverseMap.get(value); } - public Object removeValue(Object value) { - Object key = null; - if (maps[1].containsKey(value)) { - key = maps[1].remove(value); - maps[0].remove(key); + public K removeValue(Object value) { + K key = null; + if (reverseMap.containsKey(value)) { + key = reverseMap.remove(value); + normalMap.remove(key); } return key; } - public BidiMap inverseBidiMap() { + public BidiMap<V, K> inverseBidiMap() { if (inverseBidiMap == null) { - inverseBidiMap = createBidiMap(maps[1], maps[0], this); + inverseBidiMap = createBidiMap(reverseMap, normalMap, this); } return inverseBidiMap; } - + // Map views //----------------------------------------------------------------------- /** * Gets a keySet view of the map. * Changes made on the view are reflected in the map. * The set supports remove and clear but not add. - * + * * @return the keySet view */ - public Set keySet() { + public Set<K> keySet() { if (keySet == null) { - keySet = new KeySet(this); + keySet = new KeySet<K>(this); } return keySet; } @@ -247,24 +254,24 @@ public abstract class AbstractDualBidiMap implements BidiMap { /** * Creates a key set iterator. * Subclasses can override this to return iterators with different properties. - * + * * @param iterator the iterator to decorate * @return the keySet iterator */ - protected Iterator createKeySetIterator(Iterator iterator) { - return new KeySetIterator(iterator, this); + protected Iterator<K> createKeySetIterator(Iterator<K> iterator) { + return new KeySetIterator<K>(iterator, this); } /** * Gets a values view of the map. * Changes made on the view are reflected in the map. * The set supports remove and clear but not add. - * + * * @return the values view */ - public Collection values() { + public Collection<V> values() { if (values == null) { - values = new Values(this); + values = new Values<V>(this); } return values; } @@ -272,12 +279,12 @@ public abstract class AbstractDualBidiMap implements BidiMap { /** * Creates a values iterator. * Subclasses can override this to return iterators with different properties. - * + * * @param iterator the iterator to decorate * @return the values iterator */ - protected Iterator createValuesIterator(Iterator iterator) { - return new ValuesIterator(iterator, this); + protected Iterator<V> createValuesIterator(Iterator<V> iterator) { + return new ValuesIterator<V>(iterator, this); } /** @@ -288,53 +295,54 @@ public abstract class AbstractDualBidiMap implements BidiMap { * The Map Entry setValue() method only allow a new value to be set. * If the value being set is already in the map, an IllegalArgumentException * is thrown (as setValue cannot change the size of the map). - * + * * @return the entrySet view */ - public Set entrySet() { + public Set<Map.Entry<K, V>> entrySet() { if (entrySet == null) { - entrySet = new EntrySet(this); + entrySet = new EntrySet<K, V>(this); } return entrySet; } - + /** * Creates an entry set iterator. * Subclasses can override this to return iterators with different properties. - * + * * @param iterator the iterator to decorate * @return the entrySet iterator */ - protected Iterator createEntrySetIterator(Iterator iterator) { - return new EntrySetIterator(iterator, this); + protected Iterator<Map.Entry<K, V>> createEntrySetIterator(Iterator<Map.Entry<K, V>> iterator) { + return new EntrySetIterator<K, V>(iterator, this); } //----------------------------------------------------------------------- /** * Inner class View. */ - protected static abstract class View extends AbstractCollectionDecorator { - + @SuppressWarnings("serial") + protected static abstract class View<K, V, E> extends AbstractCollectionDecorator<E> { + /** The parent map */ - protected final AbstractDualBidiMap parent; - + protected final AbstractDualBidiMap<K, V> parent; + /** * Constructs a new view of the BidiMap. - * + * * @param coll the collection view being decorated * @param parent the parent BidiMap */ - protected View(Collection coll, AbstractDualBidiMap parent) { + protected View(Collection<E> coll, AbstractDualBidiMap<K, V> parent) { super(coll); this.parent = parent; } - public boolean removeAll(Collection coll) { + public boolean removeAll(Collection<?> coll) { if (parent.isEmpty() || coll.isEmpty()) { return false; } boolean modified = false; - Iterator it = iterator(); + Iterator<E> it = iterator(); while (it.hasNext()) { if (coll.contains(it.next())) { it.remove(); @@ -344,7 +352,7 @@ public abstract class AbstractDualBidiMap implements BidiMap { return modified; } - public boolean retainAll(Collection coll) { + public boolean retainAll(Collection<?> coll) { if (parent.isEmpty()) { return false; } @@ -353,7 +361,7 @@ public abstract class AbstractDualBidiMap implements BidiMap { return true; } boolean modified = false; - Iterator it = iterator(); + Iterator<E> it = iterator(); while (it.hasNext()) { if (coll.contains(it.next()) == false) { it.remove(); @@ -362,80 +370,86 @@ public abstract class AbstractDualBidiMap implements BidiMap { } return modified; } - + public void clear() { parent.clear(); } } - + //----------------------------------------------------------------------- /** * Inner class KeySet. */ - protected static class KeySet extends View implements Set { - + protected static class KeySet<K> extends View<K, Object, K> implements Set<K> { + + /** Serialization version */ + private static final long serialVersionUID = -7107935777385040694L; + /** * Constructs a new view of the BidiMap. - * + * * @param parent the parent BidiMap */ - protected KeySet(AbstractDualBidiMap parent) { - super(parent.maps[0].keySet(), parent); + @SuppressWarnings("unchecked") + protected KeySet(AbstractDualBidiMap<K, ?> parent) { + super(parent.normalMap.keySet(), (AbstractDualBidiMap<K, Object>) parent); } - public Iterator iterator() { + public Iterator<K> iterator() { return parent.createKeySetIterator(super.iterator()); } - + public boolean contains(Object key) { - return parent.maps[0].containsKey(key); + return parent.normalMap.containsKey(key); } public boolean remove(Object key) { - if (parent.maps[0].containsKey(key)) { - Object value = parent.maps[0].remove(key); - parent.maps[1].remove(value); + if (parent.normalMap.containsKey(key)) { + Object value = parent.normalMap.remove(key); + parent.reverseMap.remove(value); return true; } return false; } } - + /** * Inner class KeySetIterator. */ - protected static class KeySetIterator extends AbstractIteratorDecorator { - + protected static class KeySetIterator<K> extends AbstractIteratorDecorator<K> { + /** The parent map */ - protected final AbstractDualBidiMap parent; + protected final AbstractDualBidiMap<K, ?> parent; + /** The last returned key */ - protected Object lastKey = null; + protected K lastKey = null; + /** Whether remove is allowed at present */ protected boolean canRemove = false; - + /** * Constructor. * @param iterator the iterator to decorate * @param parent the parent map */ - protected KeySetIterator(Iterator iterator, AbstractDualBidiMap parent) { + protected KeySetIterator(Iterator<K> iterator, AbstractDualBidiMap<K, ?> parent) { super(iterator); this.parent = parent; } - - public Object next() { + + public K next() { lastKey = super.next(); canRemove = true; return lastKey; } - + public void remove() { if (canRemove == false) { throw new IllegalStateException("Iterator remove() can only be called once after next()"); } - Object value = parent.maps[0].get(lastKey); + Object value = parent.normalMap.get(lastKey); super.remove(); - parent.maps[1].remove(value); + parent.reverseMap.remove(value); lastKey = null; canRemove = false; } @@ -445,69 +459,76 @@ public abstract class AbstractDualBidiMap implements BidiMap { /** * Inner class Values. */ - protected static class Values extends View implements Set { - + protected static class Values<V> extends View<Object, V, V> implements Set<V> { + + /** Serialization version */ + private static final long serialVersionUID = 4023777119829639864L; + /** * Constructs a new view of the BidiMap. - * + * * @param parent the parent BidiMap */ - protected Values(AbstractDualBidiMap parent) { - super(parent.maps[0].values(), parent); + @SuppressWarnings("unchecked") + protected Values(AbstractDualBidiMap<?, V> parent) { + super(parent.normalMap.values(), (AbstractDualBidiMap<Object, V>) parent); } - public Iterator iterator() { + public Iterator<V> iterator() { return parent.createValuesIterator(super.iterator()); } - + public boolean contains(Object value) { - return parent.maps[1].containsKey(value); + return parent.reverseMap.containsKey(value); } public boolean remove(Object value) { - if (parent.maps[1].containsKey(value)) { - Object key = parent.maps[1].remove(value); - parent.maps[0].remove(key); + if (parent.reverseMap.containsKey(value)) { + Object key = parent.reverseMap.remove(value); + parent.normalMap.remove(key); return true; } return false; } } - + /** * Inner class ValuesIterator. */ - protected static class ValuesIterator extends AbstractIteratorDecorator { - + protected static class ValuesIterator<V> extends AbstractIteratorDecorator<V> { + /** The parent map */ - protected final AbstractDualBidiMap parent; + protected final AbstractDualBidiMap<Object, V> parent; + /** The last returned value */ - protected Object lastValue = null; + protected V lastValue = null; + /** Whether remove is allowed at present */ protected boolean canRemove = false; - + /** * Constructor. * @param iterator the iterator to decorate * @param parent the parent map */ - protected ValuesIterator(Iterator iterator, AbstractDualBidiMap parent) { + @SuppressWarnings("unchecked") + protected ValuesIterator(Iterator<V> iterator, AbstractDualBidiMap<?, V> parent) { super(iterator); - this.parent = parent; + this.parent = (AbstractDualBidiMap<Object, V>) parent; } - - public Object next() { + + public V next() { lastValue = super.next(); canRemove = true; return lastValue; } - + public void remove() { if (canRemove == false) { throw new IllegalStateException("Iterator remove() can only be called once after next()"); } super.remove(); // removes from maps[0] - parent.maps[1].remove(lastValue); + parent.reverseMap.remove(lastValue); lastValue = null; canRemove = false; } @@ -517,67 +538,72 @@ public abstract class AbstractDualBidiMap implements BidiMap { /** * Inner class EntrySet. */ - protected static class EntrySet extends View implements Set { - + protected static class EntrySet<K, V> extends View<K, V, Map.Entry<K, V>> implements Set<Map.Entry<K, V>> { + + /** Serialization version */ + private static final long serialVersionUID = 4040410962603292348L; + /** * Constructs a new view of the BidiMap. - * + * * @param parent the parent BidiMap */ - protected EntrySet(AbstractDualBidiMap parent) { - super(parent.maps[0].entrySet(), parent); + protected EntrySet(AbstractDualBidiMap<K, V> parent) { + super(parent.normalMap.entrySet(), parent); } - public Iterator iterator() { + public Iterator<Map.Entry<K, V>> iterator() { return parent.createEntrySetIterator(super.iterator()); } - + public boolean remove(Object obj) { if (obj instanceof Map.Entry == false) { return false; } - Map.Entry entry = (Map.Entry) obj; + Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj; Object key = entry.getKey(); if (parent.containsKey(key)) { - Object value = parent.maps[0].get(key); + V value = parent.normalMap.get(key); if (value == null ? entry.getValue() == null : value.equals(entry.getValue())) { - parent.maps[0].remove(key); - parent.maps[1].remove(value); + parent.normalMap.remove(key); + parent.reverseMap.remove(value); return true; } } return false; } } - + /** * Inner class EntrySetIterator. */ - protected static class EntrySetIterator extends AbstractIteratorDecorator { - + protected static class EntrySetIterator<K, V> extends AbstractIteratorDecorator<Map.Entry<K, V>> { + /** The parent map */ - protected final AbstractDualBidiMap parent; + protected final AbstractDualBidiMap<K, V> parent; + /** The last returned entry */ - protected Map.Entry last = null; + protected Map.Entry<K, V> last = null; + /** Whether remove is allowed at present */ protected boolean canRemove = false; - + /** * Constructor. * @param iterator the iterator to decorate * @param parent the parent map */ - protected EntrySetIterator(Iterator iterator, AbstractDualBidiMap parent) { + protected EntrySetIterator(Iterator<Map.Entry<K, V>> iterator, AbstractDualBidiMap<K, V> parent) { super(iterator); this.parent = parent; } - - public Object next() { - last = new MapEntry((Map.Entry) super.next(), parent); + + public Map.Entry<K, V> next() { + last = new MapEntry<K, V>(super.next(), parent); canRemove = true; return last; } - + public void remove() { if (canRemove == false) { throw new IllegalStateException("Iterator remove() can only be called once after next()"); @@ -585,7 +611,7 @@ public abstract class AbstractDualBidiMap implements BidiMap { // store value as remove may change the entry in the decorator (eg.TreeMap) Object value = last.getValue(); super.remove(); - parent.maps[1].remove(value); + parent.reverseMap.remove(value); last = null; canRemove = false; } @@ -594,117 +620,119 @@ public abstract class AbstractDualBidiMap implements BidiMap { /** * Inner class MapEntry. */ - protected static class MapEntry extends AbstractMapEntryDecorator { + protected static class MapEntry<K, V> extends AbstractMapEntryDecorator<K, V> { + + /** The parent map */ + protected final AbstractDualBidiMap<K, V> parent; - /** The parent map */ - protected final AbstractDualBidiMap parent; - /** * Constructor. * @param entry the entry to decorate * @param parent the parent map */ - protected MapEntry(Map.Entry entry, AbstractDualBidiMap parent) { + protected MapEntry(Map.Entry<K, V> entry, AbstractDualBidiMap<K, V> parent) { super(entry); this.parent = parent; } - - public Object setValue(Object value) { - Object key = MapEntry.this.getKey(); - if (parent.maps[1].containsKey(value) && - parent.maps[1].get(value) != key) { + + public V setValue(V value) { + K key = MapEntry.this.getKey(); + if (parent.reverseMap.containsKey(value) && + parent.reverseMap.get(value) != key) { throw new IllegalArgumentException("Cannot use setValue() when the object being set is already in the map"); } parent.put(key, value); - final Object oldValue = super.setValue(value); + final V oldValue = super.setValue(value); return oldValue; } } - + /** * Inner class MapIterator. */ - protected static class BidiMapIterator implements MapIterator, ResettableIterator { - + protected static class BidiMapIterator<K, V> implements MapIterator<K, V>, ResettableIterator<K> { + /** The parent map */ - protected final AbstractDualBidiMap parent; + protected final AbstractDualBidiMap<K, V> parent; + /** The iterator being wrapped */ - protected Iterator iterator; + protected Iterator<Map.Entry<K, V>> iterator; + /** The last returned entry */ - protected Map.Entry last = null; + protected Map.Entry<K, V> last = null; + /** Whether remove is allowed at present */ protected boolean canRemove = false; - + /** * Constructor. * @param parent the parent map */ - protected BidiMapIterator(AbstractDualBidiMap parent) { + protected BidiMapIterator(AbstractDualBidiMap<K, V> parent) { super(); this.parent = parent; - this.iterator = parent.maps[0].entrySet().iterator(); + this.iterator = parent.normalMap.entrySet().iterator(); } - + public boolean hasNext() { return iterator.hasNext(); } - - public Object next() { - last = (Map.Entry) iterator.next(); + + public K next() { + last = iterator.next(); canRemove = true; return last.getKey(); } - + public void remove() { if (canRemove == false) { throw new IllegalStateException("Iterator remove() can only be called once after next()"); } // store value as remove may change the entry in the decorator (eg.TreeMap) - Object value = last.getValue(); + V value = last.getValue(); iterator.remove(); - parent.maps[1].remove(value); + parent.reverseMap.remove(value); last = null; canRemove = false; } - - public Object getKey() { + + public K getKey() { if (last == null) { throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()"); } return last.getKey(); } - public Object getValue() { + public V getValue() { if (last == null) { throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()"); } return last.getValue(); } - - public Object setValue(Object value) { + + public V setValue(V value) { if (last == null) { throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()"); } - if (parent.maps[1].containsKey(value) && - parent.maps[1].get(value) != last.getKey()) { + if (parent.reverseMap.containsKey(value) && + parent.reverseMap.get(value) != last.getKey()) { throw new IllegalArgumentException("Cannot use setValue() when the object being set is already in the map"); } return parent.put(last.getKey(), value); } - + public void reset() { - iterator = parent.maps[0].entrySet().iterator(); + iterator = parent.normalMap.entrySet().iterator(); last = null; canRemove = false; } - + public String toString() { if (last != null) { return "MapIterator[" + getKey() + "=" + getValue() + "]"; - } else { - return "MapIterator[]"; } + return "MapIterator[]"; } } - + } http://git-wip-us.apache.org/repos/asf/commons-collections/blob/884baf0d/src/java/org/apache/commons/collections/bidimap/AbstractOrderedBidiMapDecorator.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/bidimap/AbstractOrderedBidiMapDecorator.java b/src/java/org/apache/commons/collections/bidimap/AbstractOrderedBidiMapDecorator.java index 7a96af6..1602ef8 100644 --- a/src/java/org/apache/commons/collections/bidimap/AbstractOrderedBidiMapDecorator.java +++ b/src/java/org/apache/commons/collections/bidimap/AbstractOrderedBidiMapDecorator.java @@ -36,9 +36,9 @@ import org.apache.commons.collections.OrderedMapIterator; * * @author Stephen Colebourne */ -public abstract class AbstractOrderedBidiMapDecorator - extends AbstractBidiMapDecorator - implements OrderedBidiMap { +public abstract class AbstractOrderedBidiMapDecorator<K, V> + extends AbstractBidiMapDecorator<K, V> + implements OrderedBidiMap<K, V> { /** * Constructor that wraps (not copies). @@ -46,7 +46,7 @@ public abstract class AbstractOrderedBidiMapDecorator * @param map the map to decorate, must not be null * @throws IllegalArgumentException if the collection is null */ - protected AbstractOrderedBidiMapDecorator(OrderedBidiMap map) { + protected AbstractOrderedBidiMapDecorator(OrderedBidiMap<K, V> map) { super(map); } @@ -54,44 +54,35 @@ public abstract class AbstractOrderedBidiMapDecorator * Gets the map being decorated. * * @return the decorated map - * @deprecated use decorated() */ - protected OrderedBidiMap getOrderedBidiMap() { - return decorated(); - } - - /** - * Gets the map being decorated. - * - * @return the decorated map - */ - protected OrderedBidiMap decorated() { - return (OrderedBidiMap) super.decorated(); + protected OrderedBidiMap<K, V> decorated() { + return (OrderedBidiMap<K, V>) super.decorated(); } //----------------------------------------------------------------------- - public OrderedMapIterator orderedMapIterator() { - return decorated().orderedMapIterator(); + public OrderedMapIterator<K, V> mapIterator() { + return decorated().mapIterator(); } - public Object firstKey() { + public K firstKey() { return decorated().firstKey(); } - public Object lastKey() { + public K lastKey() { return decorated().lastKey(); } - public Object nextKey(Object key) { + public K nextKey(K key) { return decorated().nextKey(key); } - public Object previousKey(Object key) { + public K previousKey(K key) { return decorated().previousKey(key); } - public OrderedBidiMap inverseOrderedBidiMap() { - return decorated().inverseOrderedBidiMap(); + @Override + public OrderedBidiMap<V, K> inverseBidiMap() { + return decorated().inverseBidiMap(); } } http://git-wip-us.apache.org/repos/asf/commons-collections/blob/884baf0d/src/java/org/apache/commons/collections/bidimap/AbstractSortedBidiMapDecorator.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/bidimap/AbstractSortedBidiMapDecorator.java b/src/java/org/apache/commons/collections/bidimap/AbstractSortedBidiMapDecorator.java index af56d2d..3fec108 100644 --- a/src/java/org/apache/commons/collections/bidimap/AbstractSortedBidiMapDecorator.java +++ b/src/java/org/apache/commons/collections/bidimap/AbstractSortedBidiMapDecorator.java @@ -38,9 +38,8 @@ import org.apache.commons.collections.SortedBidiMap; * * @author Stephen Colebourne */ -public abstract class AbstractSortedBidiMapDecorator - extends AbstractOrderedBidiMapDecorator - implements SortedBidiMap { +public abstract class AbstractSortedBidiMapDecorator<K, V> extends + AbstractOrderedBidiMapDecorator<K, V> implements SortedBidiMap<K, V> { /** * Constructor that wraps (not copies). @@ -48,7 +47,7 @@ public abstract class AbstractSortedBidiMapDecorator * @param map the map to decorate, must not be null * @throws IllegalArgumentException if the collection is null */ - public AbstractSortedBidiMapDecorator(SortedBidiMap map) { + public AbstractSortedBidiMapDecorator(SortedBidiMap<K, V> map) { super(map); } @@ -56,39 +55,34 @@ public abstract class AbstractSortedBidiMapDecorator * Gets the map being decorated. * * @return the decorated map - * @deprecated use decorated() */ - protected SortedBidiMap getSortedBidiMap() { - return decorated(); - } - - /** - * Gets the map being decorated. - * - * @return the decorated map - */ - protected SortedBidiMap decorated() { - return (SortedBidiMap) super.decorated(); + protected SortedBidiMap<K, V> decorated() { + return (SortedBidiMap<K, V>) super.decorated(); } //----------------------------------------------------------------------- - public SortedBidiMap inverseSortedBidiMap() { - return getSortedBidiMap().inverseSortedBidiMap(); + @Override + public SortedBidiMap<V, K> inverseBidiMap() { + return decorated().inverseBidiMap(); } - public Comparator comparator() { + public Comparator<? super K> comparator() { return decorated().comparator(); } - public SortedMap subMap(Object fromKey, Object toKey) { + public Comparator<? super V> valueComparator() { + return decorated().valueComparator(); + } + + public SortedMap<K, V> subMap(K fromKey, K toKey) { return decorated().subMap(fromKey, toKey); } - public SortedMap headMap(Object toKey) { + public SortedMap<K, V> headMap(K toKey) { return decorated().headMap(toKey); } - public SortedMap tailMap(Object fromKey) { + public SortedMap<K, V> tailMap(K fromKey) { return decorated().tailMap(fromKey); } http://git-wip-us.apache.org/repos/asf/commons-collections/blob/884baf0d/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java b/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java index 067b2a6..b0927aa 100644 --- a/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java +++ b/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java @@ -42,8 +42,7 @@ import org.apache.commons.collections.BidiMap; * @author Matthew Hawthorne * @author Stephen Colebourne */ -public class DualHashBidiMap - extends AbstractDualBidiMap implements Serializable { +public class DualHashBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements Serializable { /** Ensure serialization compatibility */ private static final long serialVersionUID = 721969328361808L; @@ -52,7 +51,7 @@ public class DualHashBidiMap * Creates an empty <code>HashBidiMap</code>. */ public DualHashBidiMap() { - super(new HashMap(), new HashMap()); + super(new HashMap<K, V>(), new HashMap<V, K>()); } /** @@ -61,8 +60,8 @@ public class DualHashBidiMap * * @param map the map whose mappings are to be placed in this map */ - public DualHashBidiMap(Map map) { - super(new HashMap(), new HashMap()); + public DualHashBidiMap(Map<K, V> map) { + super(new HashMap<K, V>(), new HashMap<V, K>()); putAll(map); } @@ -73,7 +72,7 @@ public class DualHashBidiMap * @param reverseMap the reverse direction map * @param inverseBidiMap the inverse BidiMap */ - protected DualHashBidiMap(Map normalMap, Map reverseMap, BidiMap inverseBidiMap) { + protected DualHashBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap, BidiMap<V, K> inverseBidiMap) { super(normalMap, reverseMap, inverseBidiMap); } @@ -85,21 +84,22 @@ public class DualHashBidiMap * @param inverseBidiMap the inverse BidiMap * @return new bidi map */ - protected BidiMap createBidiMap(Map normalMap, Map reverseMap, BidiMap inverseBidiMap) { - return new DualHashBidiMap(normalMap, reverseMap, inverseBidiMap); + protected BidiMap<V, K> createBidiMap(Map<V, K> normalMap, Map<K, V> reverseMap, BidiMap<K, V> inverseBidiMap) { + return new DualHashBidiMap<V, K>(normalMap, reverseMap, inverseBidiMap); } // Serialization //----------------------------------------------------------------------- private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); - out.writeObject(maps[0]); + out.writeObject(normalMap); } + @SuppressWarnings("unchecked") private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); - maps[0] = new HashMap(); - maps[1] = new HashMap(); + normalMap = new HashMap(); + reverseMap = new HashMap(); Map map = (Map) in.readObject(); putAll(map); } http://git-wip-us.apache.org/repos/asf/commons-collections/blob/884baf0d/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java b/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java index fb8aef0..5ced759 100644 --- a/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java +++ b/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You 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. @@ -48,97 +48,110 @@ import org.apache.commons.collections.map.AbstractSortedMapDecorator; * <p> * NOTE: From Commons Collections 3.1, all subclasses will use <code>TreeMap</code> * and the flawed <code>createMap</code> method is ignored. - * + * * @since Commons Collections 3.0 * @version $Id$ - * + * * @author Matthew Hawthorne * @author Stephen Colebourne */ -public class DualTreeBidiMap - extends AbstractDualBidiMap implements SortedBidiMap, Serializable { +public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements + SortedBidiMap<K, V>, Serializable { /** Ensure serialization compatibility */ private static final long serialVersionUID = 721969328361809L; - /** The comparator to use */ - protected final Comparator comparator; + + /** The key comparator to use */ + protected final Comparator<? super K> comparator; + + /** The value comparator to use */ + protected final Comparator<? super V> valueComparator; /** * Creates an empty <code>DualTreeBidiMap</code> */ public DualTreeBidiMap() { - super(new TreeMap(), new TreeMap()); + super(new TreeMap<K, V>(), new TreeMap<V, K>()); this.comparator = null; + this.valueComparator = null; } - /** + /** * Constructs a <code>DualTreeBidiMap</code> and copies the mappings from - * specified <code>Map</code>. + * specified <code>Map</code>. * * @param map the map whose mappings are to be placed in this map */ - public DualTreeBidiMap(Map map) { - super(new TreeMap(), new TreeMap()); + public DualTreeBidiMap(Map<K, V> map) { + super(new TreeMap<K, V>(), new TreeMap<V, K>()); putAll(map); this.comparator = null; + this.valueComparator = null; } - /** + /** * Constructs a <code>DualTreeBidiMap</code> using the specified Comparator. * - * @param comparator the Comparator + * @param keyComparator the Comparator */ - public DualTreeBidiMap(Comparator comparator) { - super(new TreeMap(comparator), new TreeMap(comparator)); - this.comparator = comparator; + public DualTreeBidiMap(Comparator<? super K> keyComparator, Comparator<? super V> valueComparator) { + super(new TreeMap<K, V>(keyComparator), new TreeMap<V, K>(valueComparator)); + this.comparator = keyComparator; + this.valueComparator = valueComparator; } - /** + /** * Constructs a <code>DualTreeBidiMap</code> that decorates the specified maps. * * @param normalMap the normal direction map * @param reverseMap the reverse direction map * @param inverseBidiMap the inverse BidiMap */ - protected DualTreeBidiMap(Map normalMap, Map reverseMap, BidiMap inverseBidiMap) { + protected DualTreeBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap, BidiMap<V, K> inverseBidiMap) { super(normalMap, reverseMap, inverseBidiMap); - this.comparator = ((SortedMap) normalMap).comparator(); + this.comparator = ((SortedMap<K, V>) normalMap).comparator(); + this.valueComparator = ((SortedMap<V, K>) reverseMap).comparator(); } /** * Creates a new instance of this object. - * + * * @param normalMap the normal direction map * @param reverseMap the reverse direction map * @param inverseMap the inverse BidiMap * @return new bidi map */ - protected BidiMap createBidiMap(Map normalMap, Map reverseMap, BidiMap inverseMap) { - return new DualTreeBidiMap(normalMap, reverseMap, inverseMap); + protected DualTreeBidiMap<V, K> createBidiMap(Map<V, K> normalMap, Map<K, V> reverseMap, BidiMap<K, V> inverseMap) { + return new DualTreeBidiMap<V, K>(normalMap, reverseMap, inverseMap); } //----------------------------------------------------------------------- - public Comparator comparator() { - return ((SortedMap) maps[0]).comparator(); + public Comparator<? super K> comparator() { + return ((SortedMap<K, V>) normalMap).comparator(); } - public Object firstKey() { - return ((SortedMap) maps[0]).firstKey(); + public Comparator<? super V> valueComparator() { + return ((SortedMap<V, K>) reverseMap).comparator(); + } - public Object lastKey() { - return ((SortedMap) maps[0]).lastKey(); + public K firstKey() { + return ((SortedMap<K, V>) normalMap).firstKey(); } - public Object nextKey(Object key) { + public K lastKey() { + return ((SortedMap<K, V>) normalMap).lastKey(); + } + + public K nextKey(K key) { if (isEmpty()) { return null; } - if (maps[0] instanceof OrderedMap) { - return ((OrderedMap) maps[0]).nextKey(key); + if (normalMap instanceof OrderedMap) { + return ((OrderedMap<K, ?>) normalMap).nextKey(key); } - SortedMap sm = (SortedMap) maps[0]; - Iterator it = sm.tailMap(key).keySet().iterator(); + SortedMap<K, V> sm = (SortedMap<K, V>) normalMap; + Iterator<K> it = sm.tailMap(key).keySet().iterator(); it.next(); if (it.hasNext()) { return it.next(); @@ -146,15 +159,15 @@ public class DualTreeBidiMap return null; } - public Object previousKey(Object key) { + public K previousKey(K key) { if (isEmpty()) { return null; } - if (maps[0] instanceof OrderedMap) { - return ((OrderedMap) maps[0]).previousKey(key); + if (normalMap instanceof OrderedMap) { + return ((OrderedMap<K, V>) normalMap).previousKey(key); } - SortedMap sm = (SortedMap) maps[0]; - SortedMap hm = sm.headMap(key); + SortedMap<K, V> sm = (SortedMap<K, V>) normalMap; + SortedMap<K, V> hm = sm.headMap(key); if (hm.isEmpty()) { return null; } @@ -167,81 +180,94 @@ public class DualTreeBidiMap * <p> * This implementation copies the elements to an ArrayList in order to * provide the forward/backward behaviour. - * + * * @return a new ordered map iterator */ - public OrderedMapIterator orderedMapIterator() { - return new BidiOrderedMapIterator(this); + public OrderedMapIterator<K, V> mapIterator() { + return new BidiOrderedMapIterator<K, V>(this); } - public SortedBidiMap inverseSortedBidiMap() { - return (SortedBidiMap) inverseBidiMap(); + public SortedBidiMap<V, K> inverseSortedBidiMap() { + return (SortedBidiMap<V, K>) inverseBidiMap(); } - public OrderedBidiMap inverseOrderedBidiMap() { - return (OrderedBidiMap) inverseBidiMap(); + public OrderedBidiMap<V, K> inverseOrderedBidiMap() { + return (OrderedBidiMap<V, K>) inverseBidiMap(); } //----------------------------------------------------------------------- - public SortedMap headMap(Object toKey) { - SortedMap sub = ((SortedMap) maps[0]).headMap(toKey); - return new ViewMap(this, sub); + public SortedMap<K, V> headMap(K toKey) { + SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).headMap(toKey); + return new ViewMap<K, V>(this, sub); } - public SortedMap tailMap(Object fromKey) { - SortedMap sub = ((SortedMap) maps[0]).tailMap(fromKey); - return new ViewMap(this, sub); + public SortedMap<K, V> tailMap(K fromKey) { + SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).tailMap(fromKey); + return new ViewMap<K, V>(this, sub); } - public SortedMap subMap(Object fromKey, Object toKey) { - SortedMap sub = ((SortedMap) maps[0]).subMap(fromKey, toKey); - return new ViewMap(this, sub); + public SortedMap<K, V> subMap(K fromKey, K toKey) { + SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).subMap(fromKey, toKey); + return new ViewMap<K, V>(this, sub); } - + + /** + * {@inheritDoc} + */ + @Override + public SortedBidiMap<V, K> inverseBidiMap() { + return (SortedBidiMap<V, K>) super.inverseBidiMap(); + } + //----------------------------------------------------------------------- /** * Internal sorted map view. */ - protected static class ViewMap extends AbstractSortedMapDecorator { + protected static class ViewMap<K, V> extends AbstractSortedMapDecorator<K, V> { /** The parent bidi map. */ - final DualTreeBidiMap bidi; - + final DualTreeBidiMap<K, V> bidi; + /** * Constructor. * @param bidi the parent bidi map * @param sm the subMap sorted map */ - protected ViewMap(DualTreeBidiMap bidi, SortedMap sm) { + protected ViewMap(DualTreeBidiMap<K, V> bidi, SortedMap<K, V> sm) { // the implementation is not great here... - // use the maps[0] as the filtered map, but maps[1] as the full map + // use the normalMap as the filtered map, but reverseMap as the full map // this forces containsValue and clear to be overridden - super((SortedMap) bidi.createBidiMap(sm, bidi.maps[1], bidi.inverseBidiMap)); - this.bidi = (DualTreeBidiMap) map; + super(new DualTreeBidiMap<K, V>(sm, bidi.reverseMap, bidi.inverseBidiMap)); + this.bidi = (DualTreeBidiMap<K, V>) decorated(); } - + public boolean containsValue(Object value) { - // override as default implementation jumps to [1] - return bidi.maps[0].containsValue(value); + // override as default implementation uses reverseMap + return decorated().normalMap.containsValue(value); } - + public void clear() { - // override as default implementation jumps to [1] - for (Iterator it = keySet().iterator(); it.hasNext();) { + // override as default implementation uses reverseMap + for (Iterator<K> it = keySet().iterator(); it.hasNext();) { it.next(); it.remove(); } } - - public SortedMap headMap(Object toKey) { - return new ViewMap(bidi, super.headMap(toKey)); + + public SortedMap<K, V> headMap(K toKey) { + return new ViewMap<K, V>(decorated(), super.headMap(toKey)); + } + + public SortedMap<K, V> tailMap(K fromKey) { + return new ViewMap<K, V>(decorated(), super.tailMap(fromKey)); } - public SortedMap tailMap(Object fromKey) { - return new ViewMap(bidi, super.tailMap(fromKey)); + public SortedMap<K, V> subMap(K fromKey, K toKey) { + return new ViewMap<K, V>(decorated(), super.subMap(fromKey, toKey)); } - public SortedMap subMap(Object fromKey, Object toKey) { - return new ViewMap(bidi, super.subMap(fromKey, toKey)); + @Override + protected DualTreeBidiMap<K, V> decorated() { + return (DualTreeBidiMap<K, V>) super.decorated(); } } @@ -249,99 +275,101 @@ public class DualTreeBidiMap /** * Inner class MapIterator. */ - protected static class BidiOrderedMapIterator implements OrderedMapIterator, ResettableIterator { - + protected static class BidiOrderedMapIterator<K, V> implements OrderedMapIterator<K, V>, ResettableIterator<K> { + /** The parent map */ - protected final AbstractDualBidiMap parent; + protected final AbstractDualBidiMap<K, V> parent; + /** The iterator being decorated */ - protected ListIterator iterator; + protected ListIterator<Map.Entry<K, V>> iterator; + /** The last returned entry */ - private Map.Entry last = null; - + private Map.Entry<K, V> last = null; + /** * Constructor. * @param parent the parent map */ - protected BidiOrderedMapIterator(AbstractDualBidiMap parent) { + protected BidiOrderedMapIterator(AbstractDualBidiMap<K, V> parent) { super(); this.parent = parent; - iterator = new ArrayList(parent.entrySet()).listIterator(); + iterator = new ArrayList<Map.Entry<K, V>>(parent.entrySet()).listIterator(); } - + public boolean hasNext() { return iterator.hasNext(); } - - public Object next() { - last = (Map.Entry) iterator.next(); + + public K next() { + last = iterator.next(); return last.getKey(); } - + public boolean hasPrevious() { return iterator.hasPrevious(); } - - public Object previous() { - last = (Map.Entry) iterator.previous(); + + public K previous() { + last = iterator.previous(); return last.getKey(); } - + public void remove() { iterator.remove(); parent.remove(last.getKey()); last = null; } - - public Object getKey() { + + public K getKey() { if (last == null) { throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()"); } return last.getKey(); } - public Object getValue() { + public V getValue() { if (last == null) { throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()"); } return last.getValue(); } - - public Object setValue(Object value) { + + public V setValue(V value) { if (last == null) { throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()"); } - if (parent.maps[1].containsKey(value) && - parent.maps[1].get(value) != last.getKey()) { + if (parent.reverseMap.containsKey(value) && + parent.reverseMap.get(value) != last.getKey()) { throw new IllegalArgumentException("Cannot use setValue() when the object being set is already in the map"); } return parent.put(last.getKey(), value); } - + public void reset() { - iterator = new ArrayList(parent.entrySet()).listIterator(); + iterator = new ArrayList<Map.Entry<K, V>>(parent.entrySet()).listIterator(); last = null; } - + public String toString() { if (last != null) { return "MapIterator[" + getKey() + "=" + getValue() + "]"; - } else { - return "MapIterator[]"; } + return "MapIterator[]"; } } - + // Serialization //----------------------------------------------------------------------- private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); - out.writeObject(maps[0]); + out.writeObject(normalMap); } + @SuppressWarnings("unchecked") private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); - maps[0] = new TreeMap(comparator); - maps[1] = new TreeMap(comparator); + normalMap = new TreeMap(comparator); + reverseMap = new TreeMap(comparator); Map map = (Map) in.readObject(); putAll(map); }