Note: see the next iteration.
I have this tiny library for (de)serializing lists of objects. The requirement is that each object's state may be represented textually as a single line of text. Later on, the deserialization routine attempts to map each text line to the object it encodes.
Factory.java:
package net.coderodde.lists.serial;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* This class holds the methods for serializing/deserializng the lists. The
* convention used here is that every object can be serialized to a single line
* describing the state of that object. Upon deserialization, each row should
* gracefully produce the object with its recorded state. For instance, the
* format of comma-separated values (CSV) resembles this very well.
*
* @author Rodion "rodde" Efremov
* @version 1.6
*/
public class Factory {
/**
* Serializes the all the elements. Each element should serialize to a
* single line, as the deserialization routine assumes that each line
* represents the state of exactly one element.
*
* @param <E> the actual element type.
* @param list the list of elements to serialize.
* @param serializer the element serializer.
* @return the string representation of the entire list.
*/
public static <E> String serialize(List<E> list,
LineSerializer<E> serializer) {
StringBuilder sb = new StringBuilder();
list.stream().forEach((element) -> {
sb.append(serializer.serialize(element)).append("\n");
});
return sb.toString();
}
/**
* Deserializes the entire text <code>text</code> to the list of elements
* being encoded. This routine assumes that each line describes a single
* element.
*
* @param <E> the actual element type.
* @param text the text to deserialize.
* @param deserializer the deserialization object.
* @return the list of elements.
*/
public static <E> List<E> deserialize(String text,
LineDeserializer<E> deserializer) {
return deserialize(text, deserializer, new ArrayList<>());
}
/**
* Deserializes the entire text <code>text</code> to the list of elements
* being encoded. This routine assumes that each line describes a single
* element.
*
* @param <E> the actual element type.
* @param text the text to deserialize.
* @param deserializer the deserialization object.
* @param list the list for holding the elements.
* @return the list of elements.
*/
public static <E> List<E> deserialize(String text,
LineDeserializer<E> deserializer,
List<E> list) {
if (list == null) {
return deserialize(text, deserializer);
}
list.clear();
Scanner scanner = new Scanner(text);
while (scanner.hasNextLine()) {
list.add(deserializer.deserialize(scanner.nextLine()));
}
return list;
}
}
LineSerializer.java:
package net.coderodde.lists.serial;
/**
* This interface defines the API for serializing an element to a string.
*
* @author Rodion "rodde" Efremov
* @version 1.6
* @param <E> the element type.
*/
@FunctionalInterface
public interface LineSerializer<E> {
/**
* Returns the textual representation of the input element.
*
* @param element the element to serialize.
* @return the textual representation of the input element.
*/
public String serialize(E element);
}
LineDeserializer.java:
package net.coderodde.lists.serial;
/**
* This interface defines the API for deserializing the elements from their
* textual representation.
*
* @author Rodion "rodde" Efremov
* @version 1.6
* @param <E> the element type.
*/
@FunctionalInterface
public interface LineDeserializer<E> {
/**
* Deserializes the element from its textual representation.
*
* @param text the string representing the state of the element.
* @return the actual, deserialized element.
*/
public E deserialize(String text);
}
Demo.java:
package net.coderodde.lists.serial;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
public class Demo {
public static void main(final String... args) {
// Create.
List<Integer> input = getRandomInts(100, new Random());
// Serialize.
String text = Factory.serialize(input, (e) -> e.toString());
// Deserialize.
List<Integer> output =
Factory.deserialize(text,
(e) -> Integer.parseInt(e),
new LinkedList());
System.out.println("Input list size: " + input.size());
System.out.println("Input list type: " + input.getClass().getName());
System.out.println("Output list size: " + output.size());
System.out.println("Output list type: " + output.getClass().getName());
for (int i = 0; i < input.size(); ++i) {
if (!Objects.equals(input.get(i), output.get(i))) {
throw new IllegalStateException("Lists do not agree! :-[");
}
}
System.out.println("Lists agree! :-]");
}
private static List<Integer> getRandomInts(int size, Random random) {
List<Integer> ret = new ArrayList<>();
for (int i = 0; i < size; ++i) {
ret.add(random.nextInt());
}
return ret;
}
}
So, what do you think?