make IntList serializable

This commit is contained in:
2017-09-28 19:02:43 +02:00
parent 4a762f39b9
commit a178086dfa
2 changed files with 93 additions and 3 deletions

View File

@@ -1,5 +1,6 @@
package org.lucares.collections;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
@@ -9,7 +10,7 @@ import java.util.List;
* This class does not (yet) implements all methods a java.util {@link List}
* would have.
*/
public class IntList {
public class IntList implements Serializable {
// TODO make Serializable
// TODO make Cloneable
@@ -27,6 +28,8 @@ public class IntList {
// TODO add toArray(int[] a)
// TODO remove bounds checks that are handled by java, e.g. negative indices
private static final long serialVersionUID = 2588449582065895141L;
private static final int DEFAULT_CAPACITY = 10;
/**
@@ -36,7 +39,11 @@ public class IntList {
private static final int[] EMPTY_ARRAY = {};
private int[] data;
/**
* The array containing the values. It is transient, so that we can implement
* our own serialization.
*/
transient private int[] data;
private int index = 0;
@@ -96,7 +103,7 @@ public class IntList {
/**
* Returns the number of elements this list can hold before a resize is
* necessary.
* necessary, this is the size of the internal backing array.
*
* @return the number of elements this list can hold before a resize is
* necessary
@@ -351,4 +358,45 @@ public class IntList {
return true;
}
/**
* Serialize the {@link IntList}.
* <p>
* This only serializes the used part of the data array.
*
* @serialData The length of the array containing the values, followed by the
* values.
*/
private void writeObject(final java.io.ObjectOutputStream s) throws java.io.IOException {
s.defaultWriteObject();
// write out the array length. According to the implementation in ArrayList this
// is needed to be compatible with clone.
s.writeInt(index);
for (int i = 0; i < index; i++) {
s.writeInt(data[i]);
}
}
/**
* Deserialize the {@link IntList}
*/
private void readObject(final java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
data = EMPTY_ARRAY;
s.defaultReadObject();
// Read in capacity
s.readInt(); // ignored
if (index > 0) {
final int[] local_data = new int[index];
for (int i = 0; i < index; i++) {
local_data[i] = s.readInt();
}
data = local_data;
}
}
}

View File

@@ -1,5 +1,10 @@
package org.lucares.collections;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
@@ -413,4 +418,41 @@ public class IntListTest {
return result;
}
@Test
public void testSerialize() throws IOException, ClassNotFoundException {
final IntList emptyList = new IntList(0);
internalSerializeTest(emptyList);
final IntList emptyListWithCapacity = new IntList(10);
internalSerializeTest(emptyListWithCapacity);
final IntList threeElements = new IntList(10000);
threeElements.addAll(1, 2, 3);
internalSerializeTest(threeElements);
final IntList trimmedList = new IntList(10000);
trimmedList.addAll(1, 2, 3);
trimmedList.trim();
internalSerializeTest(trimmedList);
}
private void internalSerializeTest(final IntList list) throws IOException, ClassNotFoundException {
final ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
try (final ObjectOutputStream out = new ObjectOutputStream(byteBuffer)) {
out.writeObject(list);
}
try (ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteBuffer.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteInputStream)) {
final IntList actual = (IntList) in.readObject();
Assert.assertEquals(list, actual);
Assert.assertEquals(
"The capacity of the deserialized list. Should be equal to the number of inserted "
+ "values, because we don't want to serialize the unused part of the array",
list.size(), actual.getCapacity());
}
}
}