Cleanup bidimap package: package-info.java, version, author tags, javadoc.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1353747 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Thomas Neidhart 2012-06-25 21:18:57 +00:00
parent f2086a2105
commit c94dfb59c0
12 changed files with 224 additions and 112 deletions

View File

@ -33,12 +33,10 @@ import org.apache.commons.collections.map.AbstractMapDecorator;
* But, you might want that loophole, so this class is kept simple.
*
* @since Commons Collections 3.0
* @version $Revision$
*
* @author Stephen Colebourne
* @version $Id$
*/
public abstract class AbstractBidiMapDecorator<K, V> extends AbstractMapDecorator<K, V> implements
BidiMap<K, V> {
public abstract class AbstractBidiMapDecorator<K, V>
extends AbstractMapDecorator<K, V> implements BidiMap<K, V> {
/**
* Constructor that wraps (not copies).
@ -66,14 +64,23 @@ public abstract class AbstractBidiMapDecorator<K, V> extends AbstractMapDecorato
return decorated().mapIterator();
}
/**
* {@inheritDoc}
*/
public K getKey(Object value) {
return decorated().getKey(value);
}
/**
* {@inheritDoc}
*/
public K removeValue(Object value) {
return decorated().removeValue(value);
}
/**
* {@inheritDoc}
*/
public BidiMap<V, K> inverseBidiMap() {
return decorated().inverseBidiMap();
}

View File

@ -29,18 +29,15 @@ import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
import org.apache.commons.collections.keyvalue.AbstractMapEntryDecorator;
/**
* Abstract <code>BidiMap</code> implemented using two maps.
* Abstract {@link BidiMap} implemented using two maps.
* <p>
* An implementation can be written simply by implementing the
* <code>createMap</code> method.
* {@link #createBidiMap(Map, Map, BidiMap)} method.
*
* @see DualHashBidiMap
* @see DualTreeBidiMap
* @since Commons Collections 3.0
* @version $Id$
*
* @author Matthew Hawthorne
* @author Stephen Colebourne
*/
public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
@ -132,18 +129,31 @@ public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
// Map delegation
//-----------------------------------------------------------------------
/**
* {@inheritDoc}
*/
public V get(Object key) {
return normalMap.get(key);
}
/**
* {@inheritDoc}
*/
public int size() {
return normalMap.size();
}
/**
* {@inheritDoc}
*/
public boolean isEmpty() {
return normalMap.isEmpty();
}
/**
* {@inheritDoc}
*/
public boolean containsKey(Object key) {
return normalMap.containsKey(key);
}
@ -165,6 +175,10 @@ public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
// BidiMap changes
//-----------------------------------------------------------------------
/**
* {@inheritDoc}
*/
public V put(K key, V value) {
if (normalMap.containsKey(key)) {
reverseMap.remove(normalMap.get(key));
@ -177,12 +191,18 @@ public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
return obj;
}
/**
* {@inheritDoc}
*/
public void putAll(Map<? extends K, ? extends V> map) {
for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}
/**
* {@inheritDoc}
*/
public V remove(Object key) {
V value = null;
if (normalMap.containsKey(key)) {
@ -192,11 +212,17 @@ public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
return value;
}
/**
* {@inheritDoc}
*/
public void clear() {
normalMap.clear();
reverseMap.clear();
}
/**
* {@inheritDoc}
*/
public boolean containsValue(Object value) {
return reverseMap.containsKey(value);
}
@ -218,10 +244,16 @@ public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
return new BidiMapIterator<K, V>(this);
}
/**
* {@inheritDoc}
*/
public K getKey(Object value) {
return reverseMap.get(value);
}
/**
* {@inheritDoc}
*/
public K removeValue(Object value) {
K key = null;
if (reverseMap.containsKey(value)) {
@ -231,6 +263,9 @@ public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
return key;
}
/**
* {@inheritDoc}
*/
public BidiMap<V, K> inverseBidiMap() {
if (inverseBidiMap == null) {
inverseBidiMap = createBidiMap(reverseMap, normalMap, this);
@ -657,7 +692,8 @@ public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
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");
throw new IllegalArgumentException(
"Cannot use setValue() when the object being set is already in the map");
}
parent.put(key, value);
final V oldValue = super.setValue(value);
@ -692,16 +728,19 @@ public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
this.iterator = parent.normalMap.entrySet().iterator();
}
/** {@inheritDoc} */
public boolean hasNext() {
return iterator.hasNext();
}
/** {@inheritDoc} */
public K next() {
last = iterator.next();
canRemove = true;
return last.getKey();
}
/** {@inheritDoc} */
public void remove() {
if (canRemove == false) {
throw new IllegalStateException("Iterator remove() can only be called once after next()");
@ -714,31 +753,39 @@ public abstract class AbstractDualBidiMap<K, V> implements BidiMap<K, V> {
canRemove = false;
}
/** {@inheritDoc} */
public K getKey() {
if (last == null) {
throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()");
throw new IllegalStateException(
"Iterator getKey() can only be called after next() and before remove()");
}
return last.getKey();
}
/** {@inheritDoc} */
public V getValue() {
if (last == null) {
throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()");
throw new IllegalStateException(
"Iterator getValue() can only be called after next() and before remove()");
}
return last.getValue();
}
/** {@inheritDoc} */
public V setValue(V value) {
if (last == null) {
throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()");
throw new IllegalStateException(
"Iterator setValue() can only be called after next() and before remove()");
}
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");
throw new IllegalArgumentException(
"Cannot use setValue() when the object being set is already in the map");
}
return parent.put(last.getKey(), value);
}
/** {@inheritDoc} */
public void reset() {
iterator = parent.normalMap.entrySet().iterator();
last = null;

View File

@ -32,9 +32,7 @@ import org.apache.commons.collections.OrderedMapIterator;
* But, you might want that loophole, so this class is kept simple.
*
* @since Commons Collections 3.0
* @version $Revision$
*
* @author Stephen Colebourne
* @version $Id$
*/
public abstract class AbstractOrderedBidiMapDecorator<K, V>
extends AbstractBidiMapDecorator<K, V>
@ -66,18 +64,30 @@ public abstract class AbstractOrderedBidiMapDecorator<K, V>
return decorated().mapIterator();
}
/**
* {@inheritDoc}
*/
public K firstKey() {
return decorated().firstKey();
}
/**
* {@inheritDoc}
*/
public K lastKey() {
return decorated().lastKey();
}
/**
* {@inheritDoc}
*/
public K nextKey(K key) {
return decorated().nextKey(key);
}
/**
* {@inheritDoc}
*/
public K previousKey(K key) {
return decorated().previousKey(key);
}

View File

@ -34,12 +34,10 @@ import org.apache.commons.collections.SortedBidiMap;
* But, you might want that loophole, so this class is kept simple.
*
* @since Commons Collections 3.0
* @version $Revision$
*
* @author Stephen Colebourne
* @version $Id$
*/
public abstract class AbstractSortedBidiMapDecorator<K, V> extends
AbstractOrderedBidiMapDecorator<K, V> implements SortedBidiMap<K, V> {
public abstract class AbstractSortedBidiMapDecorator<K, V>
extends AbstractOrderedBidiMapDecorator<K, V> implements SortedBidiMap<K, V> {
/**
* Constructor that wraps (not copies).
@ -67,22 +65,37 @@ public abstract class AbstractSortedBidiMapDecorator<K, V> extends
return decorated().inverseBidiMap();
}
/**
* {@inheritDoc}
*/
public Comparator<? super K> comparator() {
return decorated().comparator();
}
/**
* {@inheritDoc}
*/
public Comparator<? super V> valueComparator() {
return decorated().valueComparator();
}
/**
* {@inheritDoc}
*/
public SortedMap<K, V> subMap(K fromKey, K toKey) {
return decorated().subMap(fromKey, toKey);
}
/**
* {@inheritDoc}
*/
public SortedMap<K, V> headMap(K toKey) {
return decorated().headMap(toKey);
}
/**
* {@inheritDoc}
*/
public SortedMap<K, V> tailMap(K fromKey) {
return decorated().tailMap(fromKey);
}

View File

@ -26,21 +26,18 @@ import java.util.Map;
import org.apache.commons.collections.BidiMap;
/**
* Implementation of <code>BidiMap</code> that uses two <code>HashMap</code> instances.
* Implementation of {@link BidiMap} that uses two {@link HashMap} instances.
* <p>
* Two <code>HashMap</code> instances are used in this class.
* Two {@link HashMap} instances are used in this class.
* This provides fast lookups at the expense of storing two sets of map entries.
* Commons Collections would welcome the addition of a direct hash-based
* implementation of the <code>BidiMap</code> interface.
* implementation of the {@link BidiMap} interface.
* <p>
* NOTE: From Commons Collections 3.1, all subclasses will use <code>HashMap</code>
* NOTE: From Commons Collections 3.1, all subclasses will use {@link HashMap}
* and the flawed <code>createMap</code> method is ignored.
*
* @since Commons Collections 3.0
* @version $Id$
*
* @author Matthew Hawthorne
* @author Stephen Colebourne
*/
public class DualHashBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements Serializable {

View File

@ -37,7 +37,7 @@ import org.apache.commons.collections.SortedBidiMap;
import org.apache.commons.collections.map.AbstractSortedMapDecorator;
/**
* Implementation of <code>BidiMap</code> that uses two <code>TreeMap</code> instances.
* Implementation of {@link BidiMap} that uses two {@link TreeMap} instances.
* <p>
* The setValue() method on iterators will succeed only if the new value being set is
* not already in the bidimap.
@ -46,17 +46,14 @@ import org.apache.commons.collections.map.AbstractSortedMapDecorator;
* also be considered. It implements the interface using a dedicated design, and does
* not store each object twice, which can save on memory use.
* <p>
* NOTE: From Commons Collections 3.1, all subclasses will use <code>TreeMap</code>
* NOTE: From Commons Collections 3.1, all subclasses will use {@link TreeMap}
* 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<K, V> extends AbstractDualBidiMap<K, V> implements
SortedBidiMap<K, V>, Serializable {
public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V>
implements SortedBidiMap<K, V>, Serializable {
/** Ensure serialization compatibility */
private static final long serialVersionUID = 721969328361809L;
@ -90,9 +87,10 @@ public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements
}
/**
* Constructs a <code>DualTreeBidiMap</code> using the specified Comparator.
* Constructs a {@link DualTreeBidiMap} using the specified {@link Comparator}.
*
* @param keyComparator the Comparator
* @param keyComparator the comparator
* @param valueComparator the values comparator to use
*/
public DualTreeBidiMap(Comparator<? super K> keyComparator, Comparator<? super V> valueComparator) {
super(new TreeMap<K, V>(keyComparator), new TreeMap<V, K>(valueComparator));
@ -101,7 +99,7 @@ public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements
}
/**
* Constructs a <code>DualTreeBidiMap</code> that decorates the specified maps.
* Constructs a {@link DualTreeBidiMap} that decorates the specified maps.
*
* @param normalMap the normal direction map
* @param reverseMap the reverse direction map
@ -127,23 +125,39 @@ public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements
}
//-----------------------------------------------------------------------
/**
* {@inheritDoc}
*/
public Comparator<? super K> comparator() {
return ((SortedMap<K, V>) normalMap).comparator();
}
/**
* {@inheritDoc}
*/
public Comparator<? super V> valueComparator() {
return ((SortedMap<V, K>) reverseMap).comparator();
}
/**
* {@inheritDoc}
*/
public K firstKey() {
return ((SortedMap<K, V>) normalMap).firstKey();
}
/**
* {@inheritDoc}
*/
public K lastKey() {
return ((SortedMap<K, V>) normalMap).lastKey();
}
/**
* {@inheritDoc}
*/
public K nextKey(K key) {
if (isEmpty()) {
return null;
@ -160,6 +174,9 @@ public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements
return null;
}
/**
* {@inheritDoc}
*/
public K previousKey(K key) {
if (isEmpty()) {
return null;
@ -189,25 +206,41 @@ public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements
return new BidiOrderedMapIterator<K, V>(this);
}
/**
* {@inheritDoc}
*/
public SortedBidiMap<V, K> inverseSortedBidiMap() {
return inverseBidiMap();
}
/**
* {@inheritDoc}
*/
public OrderedBidiMap<V, K> inverseOrderedBidiMap() {
return inverseBidiMap();
}
//-----------------------------------------------------------------------
/**
* {@inheritDoc}
*/
public SortedMap<K, V> headMap(K toKey) {
SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).headMap(toKey);
return new ViewMap<K, V>(this, sub);
}
/**
* {@inheritDoc}
*/
public SortedMap<K, V> tailMap(K fromKey) {
SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).tailMap(fromKey);
return new ViewMap<K, V>(this, sub);
}
/**
* {@inheritDoc}
*/
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);
@ -313,55 +346,68 @@ public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements
iterator = new ArrayList<Map.Entry<K, V>>(parent.entrySet()).listIterator();
}
/** {@inheritDoc} */
public boolean hasNext() {
return iterator.hasNext();
}
/** {@inheritDoc} */
public K next() {
last = iterator.next();
return last.getKey();
}
/** {@inheritDoc} */
public boolean hasPrevious() {
return iterator.hasPrevious();
}
/** {@inheritDoc} */
public K previous() {
last = iterator.previous();
return last.getKey();
}
/** {@inheritDoc} */
public void remove() {
iterator.remove();
parent.remove(last.getKey());
last = null;
}
/** {@inheritDoc} */
public K getKey() {
if (last == null) {
throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()");
throw new IllegalStateException(
"Iterator getKey() can only be called after next() and before remove()");
}
return last.getKey();
}
/** {@inheritDoc} */
public V getValue() {
if (last == null) {
throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()");
throw new IllegalStateException(
"Iterator getValue() can only be called after next() and before remove()");
}
return last.getValue();
}
/** {@inheritDoc} */
public V setValue(V value) {
if (last == null) {
throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()");
throw new IllegalStateException(
"Iterator setValue() can only be called after next() and before remove()");
}
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");
throw new IllegalArgumentException(
"Cannot use setValue() when the object being set is already in the map");
}
return parent.put(last.getKey(), value);
}
/** {@inheritDoc} */
public void reset() {
iterator = new ArrayList<Map.Entry<K, V>>(parent.entrySet()).listIterator();
last = null;

View File

@ -31,7 +31,9 @@ import org.apache.commons.collections.OrderedIterator;
import org.apache.commons.collections.OrderedMapIterator;
import org.apache.commons.collections.iterators.EmptyOrderedMapIterator;
import org.apache.commons.collections.keyvalue.UnmodifiableMapEntry;
import static org.apache.commons.collections.bidimap.TreeBidiMap.DataElement.*;
import static org.apache.commons.collections.bidimap.TreeBidiMap.DataElement.KEY;
import static org.apache.commons.collections.bidimap.TreeBidiMap.DataElement.VALUE;
/**
* Red-Black tree-based implementation of BidiMap where all objects added
@ -55,7 +57,7 @@ import static org.apache.commons.collections.bidimap.TreeBidiMap.DataElement.*;
* {@link DualHashBidiMap} implementations use this approach.
* <p>
* This solution keeps minimizes the data storage by holding data only once.
* The red-black algorithm is based on java util TreeMap, but has been modified
* The red-black algorithm is based on {@link java.util.TreeMap}, but has been modified
* to simultaneously map a tree node by key and by value. This doubles the
* cost of put operations (but so does using two TreeMaps), and nearly doubles
* the cost of remove operations (there is a savings in that the lookup of the
@ -68,11 +70,7 @@ import static org.apache.commons.collections.bidimap.TreeBidiMap.DataElement.*;
* UnsupportedOperationException on attempts to call that method.
*
* @since Commons Collections 3.0 (previously DoubleOrderedMap v2.0)
* @version $Revision$
*
* @author Marc Johnson
* @author Stephen Colebourne
* @author Matt Benson
* @version $Id$
*/
public class TreeBidiMap<K extends Comparable<K>, V extends Comparable<V>> implements OrderedBidiMap<K, V> {
@ -83,6 +81,8 @@ public class TreeBidiMap<K extends Comparable<K>, V extends Comparable<V>> imple
/**
* Create a new TreeBidiMap.DataElement.
*
* @param description the description for the element
*/
private DataElement(String description) {
this.description = description;

View File

@ -29,14 +29,12 @@ import org.apache.commons.collections.map.UnmodifiableEntrySet;
import org.apache.commons.collections.set.UnmodifiableSet;
/**
* Decorates another <code>BidiMap</code> to ensure it can't be altered.
* Decorates another {@link BidiMap} to ensure it can't be altered.
* <p>
* Attempts to modify it will result in an UnsupportedOperationException.
*
* @since Commons Collections 3.0
* @version $Revision$
*
* @author Stephen Colebourne
* @version $Id$
*/
public final class UnmodifiableBidiMap<K, V>
extends AbstractBidiMapDecorator<K, V> implements Unmodifiable {
@ -49,6 +47,8 @@ public final class UnmodifiableBidiMap<K, V>
* <p>
* If the map passed in is already unmodifiable, it is returned.
*
* @param <K> the key type
* @param <V> the value type
* @param map the map to decorate, must not be null
* @return an unmodifiable BidiMap
* @throws IllegalArgumentException if map is null

View File

@ -29,14 +29,12 @@ import org.apache.commons.collections.map.UnmodifiableEntrySet;
import org.apache.commons.collections.set.UnmodifiableSet;
/**
* Decorates another <code>OrderedBidiMap</code> to ensure it can't be altered.
* Decorates another {@link OrderedBidiMap} to ensure it can't be altered.
* <p>
* Attempts to modify it will result in an UnsupportedOperationException.
*
* @since Commons Collections 3.0
* @version $Revision$
*
* @author Stephen Colebourne
* @version $Id$
*/
public final class UnmodifiableOrderedBidiMap<K, V>
extends AbstractOrderedBidiMapDecorator<K, V> implements Unmodifiable {
@ -49,6 +47,8 @@ public final class UnmodifiableOrderedBidiMap<K, V>
* <p>
* If the map passed in is already unmodifiable, it is returned.
*
* @param <K> the key type
* @param <V> the value type
* @param map the map to decorate, must not be null
* @return an unmodifiable OrderedBidiMap
* @throws IllegalArgumentException if map is null

View File

@ -31,14 +31,12 @@ import org.apache.commons.collections.map.UnmodifiableSortedMap;
import org.apache.commons.collections.set.UnmodifiableSet;
/**
* Decorates another <code>SortedBidiMap</code> to ensure it can't be altered.
* Decorates another {@link SortedBidiMap} to ensure it can't be altered.
* <p>
* Attempts to modify it will result in an UnsupportedOperationException.
* Attempts to modify it will result in an {@link UnsupportedOperationException}.
*
* @since Commons Collections 3.0
* @version $Revision$
*
* @author Stephen Colebourne
* @version $Id$
*/
public final class UnmodifiableSortedBidiMap<K, V>
extends AbstractSortedBidiMapDecorator<K, V> implements Unmodifiable {
@ -51,6 +49,8 @@ public final class UnmodifiableSortedBidiMap<K, V>
* <p>
* If the map passed in is already unmodifiable, it is returned.
*
* @param <K> the key type
* @param <V> the value type
* @param map the map to decorate, must not be null
* @return an unmodifiable SortedBidiMap
* @throws IllegalArgumentException if map is null

View File

@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This package contains implementations of the
* {@link org.apache.commons.collections.BidiMap BidiMap},
* {@link org.apache.commons.collections.OrderedBidiMap OrderedBidiMap} and
* {@link org.apache.commons.collections.SortedBidiMap SortedBidiMap} interfaces.
* A BidiMap is an extension to Map that allows keys and values to be looked up with equal ease.
* One example usage is a system communicating to a legacy datasource that must convert codes
* from the new format to the old format and vice versa.
* <p>
* The following implementations are provided in the package:
* <ul>
* <li>DualHashBidiMap - uses two HashMaps to implement BidiMap
* <li>DualTreeBidiMap - uses two TreeMaps to implement SortedBidiMap
* <li>TreeBidiMap - red-black tree implementation of OrderedBidiMap
* </ul>
* <p>
* The following decorators are provided in the package:
* <ul>
* <li>Unmodifiable - ensures the map cannot be altered
* </ul>
*
* @version $Id$
*/
package org.apache.commons.collections.bidimap;

View File

@ -1,48 +0,0 @@
<!-- $Id$ -->
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
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.
See the License for the specific language governing permissions and
limitations under the License.
-->
<BODY>
<p>
This package contains implementations of the
{@link org.apache.commons.collections.BidiMap BidiMap},
{@link org.apache.commons.collections.OrderedBidiMap OrderedBidiMap} and
{@link org.apache.commons.collections.SortedBidiMap SortedBidiMap} interfaces.
A BidiMap is an extension to Map that allows keys and values to be looked up with equal ease.
One example usage is a system communicating to a legacy datasource that must convert codes
from the new format to the old format and vice versa.
<p>
The following implementations are provided in the package:
<ul>
<li>DualHashBidiMap - uses two HashMaps to implement BidiMap
<li>DualTreeBidiMap - uses two TreeMaps to implement SortedBidiMap
<li>TreeBidiMap - red-black tree implementation of OrderedBidiMap
</ul>
<p>
The following decorators are provided in the package:
<ul>
<li>Unmodifiable - ensures the map cannot be altered
<!--
<li>Synchronized - synchronizes method access for multi-threaded environments
<li>Predicated - ensures that only elements that are valid according to a predicate can be added
<li>Typed - ensures that only elements that are of a specific type can be added
<li>Transformed - transforms each element added
<li>FixedSize - ensures that the size of the map cannot change
<li>Lazy - creates objects in the map on demand
<li>ListOrdered - ensures that insertion order is retained-->
</ul>
</pre>
</BODY>