diff --git a/RELEASE-NOTES.html b/RELEASE-NOTES.html index f10ca05e1..557dc6290 100644 --- a/RELEASE-NOTES.html +++ b/RELEASE-NOTES.html @@ -30,12 +30,14 @@ No interface changes, or deprecations have occurred.
Flat3Map
if the size is likely to grow beyond 3.
*
* @since Commons Collections 3.0
- * @version $Revision: 1.13 $ $Date: 2004/02/18 01:13:19 $
+ * @version $Revision: 1.14 $ $Date: 2004/03/31 23:18:56 $
*
* @author Stephen Colebourne
*/
-public class Flat3Map implements IterableMap {
+public class Flat3Map implements IterableMap, Serializable, Cloneable {
+
+ /** Serialization version */
+ private static final long serialVersionUID = -6701087419741928296L;
/** The size of the map, used while in flat mode */
- private int size;
+ private transient int size;
/** Hash, used while in flat mode */
- private int hash1;
+ private transient int hash1;
/** Hash, used while in flat mode */
- private int hash2;
+ private transient int hash2;
/** Hash, used while in flat mode */
- private int hash3;
+ private transient int hash3;
/** Key, used while in flat mode */
- private Object key1;
+ private transient Object key1;
/** Key, used while in flat mode */
- private Object key2;
+ private transient Object key2;
/** Key, used while in flat mode */
- private Object key3;
+ private transient Object key3;
/** Value, used while in flat mode */
- private Object value1;
+ private transient Object value1;
/** Value, used while in flat mode */
- private Object value2;
+ private transient Object value2;
/** Value, used while in flat mode */
- private Object value3;
+ private transient Object value3;
/** Map, used while in delegate mode */
- private HashedMap delegateMap;
+ private transient HashedMap delegateMap;
/**
* Constructor.
@@ -344,7 +351,7 @@ public class Flat3Map implements IterableMap {
* Converts the flat map data to a HashMap.
*/
private void convertToMap() {
- delegateMap = new HashedMap();
+ delegateMap = createDelegateMap();
switch (size) { // drop through
case 3:
delegateMap.put(key3, value3);
@@ -360,6 +367,16 @@ public class Flat3Map implements IterableMap {
value1 = value2 = value3 = null;
}
+ /**
+ * Create an instance of the map used for storage when in delegation mode.
+ * This can be overridden by subclasses.
+ *
+ * @return a new HashedMap or subclass
+ */
+ protected HashedMap createDelegateMap() {
+ return new HashedMap();
+ }
+
/**
* Removes the specified mapping from this map.
*
@@ -945,8 +962,52 @@ public class Flat3Map implements IterableMap {
return getValue();
}
}
-
+
//-----------------------------------------------------------------------
+ /**
+ * Write the map out using a custom routine.
+ */
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeInt(size());
+ for (MapIterator it = mapIterator(); it.hasNext();) {
+ out.writeObject(it.next()); // key
+ out.writeObject(it.getValue()); // value
+ }
+ }
+
+ /**
+ * Read the map in using a custom routine.
+ */
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ int count = in.readInt();
+ if (count > 3) {
+ delegateMap = createDelegateMap();
+ }
+ for (int i = count; i > 0; i--) {
+ put(in.readObject(), in.readObject());
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Clones the map without cloning the keys or values.
+ *
+ * @return a shallow clone
+ */
+ public Object clone() {
+ try {
+ Flat3Map cloned = (Flat3Map) super.clone();
+ if (cloned.delegateMap != null) {
+ cloned.delegateMap = (HashedMap) cloned.delegateMap.clone();
+ }
+ return cloned;
+ } catch (CloneNotSupportedException ex) {
+ throw new InternalError();
+ }
+ }
+
/**
* Compares this map with another.
*
diff --git a/src/test/org/apache/commons/collections/map/TestFlat3Map.java b/src/test/org/apache/commons/collections/map/TestFlat3Map.java
index dd8405090..33ae859ad 100644
--- a/src/test/org/apache/commons/collections/map/TestFlat3Map.java
+++ b/src/test/org/apache/commons/collections/map/TestFlat3Map.java
@@ -15,6 +15,10 @@
*/
package org.apache.commons.collections.map;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.util.Map;
import junit.framework.Test;
@@ -27,12 +31,17 @@ import org.apache.commons.collections.iterators.AbstractTestMapIterator;
/**
* JUnit tests.
*
- * @version $Revision: 1.6 $ $Date: 2004/02/18 01:20:37 $
+ * @version $Revision: 1.7 $ $Date: 2004/03/31 23:18:56 $
*
* @author Stephen Colebourne
*/
public class TestFlat3Map extends AbstractTestIterableMap {
+ private static final Integer ONE = new Integer(1);
+ private static final Integer TWO = new Integer(2);
+ private static final String TEN = "10";
+ private static final String TWENTY = "20";
+
public TestFlat3Map(String testName) {
super(testName);
}
@@ -49,6 +58,136 @@ public class TestFlat3Map extends AbstractTestIterableMap {
return new Flat3Map();
}
+ //-----------------------------------------------------------------------
+ public void testClone2() {
+ Flat3Map map = new Flat3Map();
+ assertEquals(0, map.size());
+ map.put(ONE, TEN);
+ map.put(TWO, TWENTY);
+ assertEquals(2, map.size());
+ assertEquals(true, map.containsKey(ONE));
+ assertEquals(true, map.containsKey(TWO));
+ assertSame(TEN, map.get(ONE));
+ assertSame(TWENTY, map.get(TWO));
+
+ // clone works (size = 2)
+ Flat3Map cloned = (Flat3Map) map.clone();
+ assertEquals(2, cloned.size());
+ assertEquals(true, cloned.containsKey(ONE));
+ assertEquals(true, cloned.containsKey(TWO));
+ assertSame(TEN, cloned.get(ONE));
+ assertSame(TWENTY, cloned.get(TWO));
+
+ // change original doesn't change clone
+ map.put(TEN, ONE);
+ map.put(TWENTY, TWO);
+ assertEquals(4, map.size());
+ assertEquals(2, cloned.size());
+ assertEquals(true, cloned.containsKey(ONE));
+ assertEquals(true, cloned.containsKey(TWO));
+ assertSame(TEN, cloned.get(ONE));
+ assertSame(TWENTY, cloned.get(TWO));
+ }
+ public void testClone4() {
+ Flat3Map map = new Flat3Map();
+ assertEquals(0, map.size());
+ map.put(ONE, TEN);
+ map.put(TWO, TWENTY);
+ map.put(TEN, ONE);
+ map.put(TWENTY, TWO);
+
+ // clone works (size = 4)
+ Flat3Map cloned = (Flat3Map) map.clone();
+ assertEquals(4, map.size());
+ assertEquals(4, cloned.size());
+ assertEquals(true, cloned.containsKey(ONE));
+ assertEquals(true, cloned.containsKey(TWO));
+ assertEquals(true, cloned.containsKey(TEN));
+ assertEquals(true, cloned.containsKey(TWENTY));
+ assertSame(TEN, cloned.get(ONE));
+ assertSame(TWENTY, cloned.get(TWO));
+ assertSame(ONE, cloned.get(TEN));
+ assertSame(TWO, cloned.get(TWENTY));
+
+ // change original doesn't change clone
+ map.clear();
+ assertEquals(0, map.size());
+ assertEquals(4, cloned.size());
+ assertEquals(true, cloned.containsKey(ONE));
+ assertEquals(true, cloned.containsKey(TWO));
+ assertEquals(true, cloned.containsKey(TEN));
+ assertEquals(true, cloned.containsKey(TWENTY));
+ assertSame(TEN, cloned.get(ONE));
+ assertSame(TWENTY, cloned.get(TWO));
+ assertSame(ONE, cloned.get(TEN));
+ assertSame(TWO, cloned.get(TWENTY));
+ }
+
+ public void testSerialisation0() throws Exception {
+ Flat3Map map = new Flat3Map();
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bout);
+ out.writeObject(map);
+ byte[] bytes = bout.toByteArray();
+ out.close();
+ ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
+ ObjectInputStream in = new ObjectInputStream(bin);
+ Flat3Map ser = (Flat3Map) in.readObject();
+ in.close();
+ assertEquals(0, map.size());
+ assertEquals(0, ser.size());
+ }
+
+ public void testSerialisation2() throws Exception {
+ Flat3Map map = new Flat3Map();
+ map.put(ONE, TEN);
+ map.put(TWO, TWENTY);
+
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bout);
+ out.writeObject(map);
+ byte[] bytes = bout.toByteArray();
+ out.close();
+ ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
+ ObjectInputStream in = new ObjectInputStream(bin);
+ Flat3Map ser = (Flat3Map) in.readObject();
+ in.close();
+ assertEquals(2, map.size());
+ assertEquals(2, ser.size());
+ assertEquals(true, ser.containsKey(ONE));
+ assertEquals(true, ser.containsKey(TWO));
+ assertEquals(TEN, ser.get(ONE));
+ assertEquals(TWENTY, ser.get(TWO));
+ }
+
+ public void testSerialisation4() throws Exception {
+ Flat3Map map = new Flat3Map();
+ map.put(ONE, TEN);
+ map.put(TWO, TWENTY);
+ map.put(TEN, ONE);
+ map.put(TWENTY, TWO);
+
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bout);
+ out.writeObject(map);
+ byte[] bytes = bout.toByteArray();
+ out.close();
+ ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
+ ObjectInputStream in = new ObjectInputStream(bin);
+ Flat3Map ser = (Flat3Map) in.readObject();
+ in.close();
+ assertEquals(4, map.size());
+ assertEquals(4, ser.size());
+ assertEquals(true, ser.containsKey(ONE));
+ assertEquals(true, ser.containsKey(TWO));
+ assertEquals(true, ser.containsKey(TEN));
+ assertEquals(true, ser.containsKey(TWENTY));
+ assertEquals(TEN, ser.get(ONE));
+ assertEquals(TWENTY, ser.get(TWO));
+ assertEquals(ONE, ser.get(TEN));
+ assertEquals(TWO, ser.get(TWENTY));
+ }
+
//-----------------------------------------------------------------------
public BulkTest bulkTestMapIterator() {
return new TestFlatMapIterator();
@@ -96,4 +235,19 @@ public class TestFlat3Map extends AbstractTestIterableMap {
TestFlat3Map.this.verify();
}
}
+
+ public String getCompatibilityVersion() {
+ return "3.1";
+ }
+
+// public void testCreate() throws Exception {
+// resetEmpty();
+// writeExternalFormToDisk(
+// (java.io.Serializable) map,
+// "D:/dev/collections/data/test/Flat3Map.emptyCollection.version3.1.obj");
+// resetFull();
+// writeExternalFormToDisk(
+// (java.io.Serializable) map,
+// "D:/dev/collections/data/test/Flat3Map.fullCollection.version3.1.obj");
+// }
}