matth 2003/09/23 13:29:34
Modified: collections/src/test/org/apache/commons/collections
TestAll.java
Added: collections/src/java/org/apache/commons/collections
HashBidiMap.java
collections/src/test/org/apache/commons/collections
TestBidiMap.java TestHashBidiMap.java
Log:
Added initial implementation of HashBidiMap, plus tests.
Revision Changes Path
1.1
jakarta-commons/collections/src/java/org/apache/commons/collections/HashBidiMap.java
Index: HashBidiMap.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/HashBidiMap.java,v
1.1 2003/09/23 20:29:34 matth Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.collections;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Default implementation of <code>BidiMap</code>.
*
* @since Commons Collections 3.0
* @version $Id: HashBidiMap.java,v 1.1 2003/09/23 20:29:34 matth Exp $
*
* @author Matthew Hawthorne
*/
public class HashBidiMap extends AbstractMap implements BidiMap {
/**
* Delegate map array. The first map contains standards entries, and the
* second contains inverses.
*/
final Map[] maps = new Map[] { new HashMap(), new HashMap()};
/**
* Inverse view of this map.
*/
private final BidiMap inverseBidiMap = new InverseBidiMap();
/**
* Creates an empty <code>HashBidiMap</code>
*/
public HashBidiMap() {}
/**
* Constructs a new <tt>HashMap</tt> with the same mappings as the
* specified <tt>Map</tt>.
*
* @param m the map whose mappings are to be placed in this map.
*/
public HashBidiMap(Map m) {
putAll(m);
}
public Object getKey(Object value) {
return maps[1].get(value);
}
public BidiMap inverseBidiMap() {
return inverseBidiMap;
}
public Object removeKey(Object value) {
final Object key = maps[1].get(value);
return remove(key);
}
public Object put(Object key, Object value) {
final Object obj = maps[0].put(key, value);
maps[1].put(value, key);
return obj;
}
public Set entrySet() {
// The entrySet is the root of most Map methods, care must be taken not
// to reference instance methods like size()
// Creates anonymous AbstractSet
return new AbstractSet() {
public Iterator iterator() {
// Creates anonymous Iterator
return new Iterator() {
// Delegate iterator.
final Iterator it = maps[0].entrySet().iterator();
// Current iterator entry
Map.Entry currentEntry;
public void remove() {
// Removes from standard and inverse Maps.
// Object must be removed using the iterator or a
// ConcurrentModificationException is thrown
it.remove();
HashBidiMap.this.maps[1].remove(
currentEntry.getValue());
}
public boolean hasNext() {
return it.hasNext();
}
public Object next() {
currentEntry = (Map.Entry)it.next();
return currentEntry;
};
}; // anonymous Iterator
}
public boolean remove(Object obj) {
// XXX Throws ClassCastException if obj is not a Map.Entry.
// Is this acceptable?
final Object removed =
HashBidiMap.this.remove(((Map.Entry)obj).getKey());
return removed != null;
}
public int size() {
return HashBidiMap.this.maps[0].size();
}
}; // anonymous AbstractSet
} // entrySet()
/**
* Inverse view of this BidiMap.
*/
private final class InverseBidiMap extends AbstractMap implements BidiMap {
public Object getKey(Object value) {
return HashBidiMap.this.get(value);
}
public BidiMap inverseBidiMap() {
return HashBidiMap.this;
}
public Object removeKey(Object value) {
return HashBidiMap.this.remove(value);
}
public Set entrySet() {
// Gets entry set from outer class
final Set entrySet = HashBidiMap.this.entrySet();
// Returns anonymous Set
return new AbstractSet() {
public int size() {
return HashBidiMap.this.size();
}
public Iterator iterator() {
final Iterator delegate = entrySet.iterator();
// Returns anonymous Iterator
return new Iterator() {
public boolean hasNext() {
return delegate.hasNext();
}
public Object next() {
final Map.Entry entry = (Map.Entry)delegate.next();
return new DefaultMapEntry(
entry.getValue(),
entry.getKey());
}
public void remove() {
delegate.remove();
}
}; // anonymous Iterator
}
}; // anonymous AbstractSet
} // entrySet()
} // InverseBidiMap
} // HashBidiMap
1.48 +3 -2
jakarta-commons/collections/src/test/org/apache/commons/collections/TestAll.java
Index: TestAll.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/TestAll.java,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- TestAll.java 20 Sep 2003 16:58:19 -0000 1.47
+++ TestAll.java 23 Sep 2003 20:29:34 -0000 1.48
@@ -104,6 +104,7 @@
suite.addTest(TestFastTreeMap.suite());
suite.addTest(TestFastTreeMap1.suite());
suite.addTest(TestHashBag.suite());
+ suite.addTest(TestHashBidiMap.suite());
suite.addTest(TestIteratorUtils.suite());
suite.addTest(TestLRUMap.suite());
suite.addTest(TestMultiHashMap.suite());
1.1
jakarta-commons/collections/src/test/org/apache/commons/collections/TestBidiMap.java
Index: TestBidiMap.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/TestBidiMap.java,v
1.1 2003/09/23 20:29:34 matth Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.collections;
import java.util.Map;
/**
* JUnit tests.
*
* @author Matthew Hawthorne
* @version $Id: TestBidiMap.java,v 1.1 2003/09/23 20:29:34 matth Exp $
* @see org.apache.commons.collections.BidiMap
*/
public abstract class TestBidiMap extends TestMap {
// Test data.
private static final Object KEY = "key1";
private static final Object VALUE = "value1";
private static final Object[][] entries =
new Object[][] {
new Object[] { KEY, VALUE },
new Object[] { "key2", "value2" },
new Object[] { "key3", "value3" }
};
public TestBidiMap(String testName) {
super(testName);
}
/**
* Creates an empty <code>BidiMap</code> implementation.
*
* @return an empty <code>BidiMap</code> implementation.
*/
protected abstract BidiMap createBidiMap();
// testGetKey
public void testGetKey() {
testGetKey(createBidiMapWithData(), entries[0][0], entries[0][1]);
}
public void testGetKeyInverse() {
testGetKey(
createBidiMapWithData().inverseBidiMap(),
entries[0][1],
entries[0][0]);
}
private final void testGetKey(BidiMap map, Object key, Object value) {
assertEquals("Value not found for key.", value, map.get(key));
assertEquals("Key not found for value.", key, map.getKey(value));
}
// testInverse
public void testInverse() {
final BidiMap map = createBidiMapWithData();
final BidiMap inverseMap = map.inverseBidiMap();
assertSame(
"Inverse of inverse is not equal to original.",
map,
inverseMap.inverseBidiMap());
assertEquals(
"Value not found for key.",
entries[0][0],
inverseMap.get(entries[0][1]));
assertEquals(
"Key not found for value.",
entries[0][1],
inverseMap.getKey(entries[0][0]));
}
// Removal tests
public void testClear() {
BidiMap map = createBidiMapWithData();
map.clear();
assertTrue("Map was not cleared.", map.isEmpty());
assertTrue(
"Inverse map was not cleared.",
map.inverseBidiMap().isEmpty());
// Tests clear on inverse
map = createBidiMapWithData().inverseBidiMap();
map.clear();
assertTrue("Map was not cleared.", map.isEmpty());
assertTrue(
"Inverse map was not cleared.",
map.inverseBidiMap().isEmpty());
}
public void testRemove() {
remove(createBidiMapWithData(), KEY);
remove(createBidiMapWithData().inverseBidiMap(), VALUE);
removeKey(createBidiMapWithData(), VALUE);
removeKey(createBidiMapWithData().inverseBidiMap(), KEY);
}
private final void remove(BidiMap map, Object key) {
final Object value = map.remove(key);
assertTrue("Key was not removed.", !map.containsKey(key));
assertNull("Value was not removed.", map.getKey(value));
}
private final void removeKey(BidiMap map, Object value) {
final Object key = map.removeKey(value);
assertTrue("Key was not removed.", !map.containsKey(key));
assertNull("Value was not removed.", map.getKey(value));
}
public void testRemoveByKeySet() {
removeByKeySet(createBidiMapWithData(), KEY, VALUE);
removeByKeySet(createBidiMapWithData().inverseBidiMap(), VALUE, KEY);
}
private final void removeByKeySet(BidiMap map, Object key, Object value) {
map.keySet().remove(key);
assertTrue("Key was not removed.", !map.containsKey(key));
assertTrue("Value was not removed.", !map.containsValue(value));
assertTrue(
"Key was not removed from inverse map.",
!map.inverseBidiMap().containsValue(key));
assertTrue(
"Value was not removed from inverse map.",
!map.inverseBidiMap().containsKey(value));
}
public void testRemoveByEntrySet() {
removeByEntrySet(createBidiMapWithData(), KEY, VALUE);
removeByEntrySet(createBidiMapWithData().inverseBidiMap(), VALUE, KEY);
}
private final void removeByEntrySet(
BidiMap map,
Object key,
Object value) {
map.entrySet().remove(new DefaultMapEntry(key, value));
assertTrue("Key was not removed.", !map.containsKey(key));
assertTrue("Value was not removed.", !map.containsValue(value));
assertTrue(
"Key was not removed from inverse map.",
!map.inverseBidiMap().containsValue(key));
assertTrue(
"Value was not removed from inverse map.",
!map.inverseBidiMap().containsKey(value));
}
// ----------------------------------------------------------------
// Data generation methods
// ----------------------------------------------------------------
protected Map makeEmptyMap() {
return createBidiMap();
}
private final BidiMap createBidiMapWithData() {
final BidiMap map = createBidiMap();
fillMap(map);
return map;
}
private static final void fillMap(BidiMap map) {
for (int i = 0; i < entries.length; i++) {
map.put(entries[i][0], entries[i][1]);
}
}
} // TestBidiMap
1.1
jakarta-commons/collections/src/test/org/apache/commons/collections/TestHashBidiMap.java
Index: TestHashBidiMap.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/TestHashBidiMap.java,v
1.1 2003/09/23 20:29:34 matth Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.collections;
import junit.framework.Test;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
/**
* JUnit tests.
*
* @author Matthew Hawthorne
* @version $Id: TestHashBidiMap.java,v 1.1 2003/09/23 20:29:34 matth Exp $
* @see org.apache.commons.collections.HashBidiMap
*/
public class TestHashBidiMap extends TestBidiMap {
public static void main(String[] args) {
TestRunner.run(suite());
}
public static Test suite() {
return new TestSuite(TestHashBidiMap.class);
}
public TestHashBidiMap(String testName) {
super(testName);
}
protected BidiMap createBidiMap() {
return new HashBidiMap();
}
} // TestHashBidiMap
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]