See the previous and initial iteration. See the next iteration.
I have mainly refactored the code and made it a little bit robust (if serialization of a single object produces a string with new line character(s), an exception is thrown as the deserialization routine relies on assumption that the object string representations are separated by new line characters).
My code at this point:
StringSerializer.java:
package net.coderodde.lists.serial;
import java.util.List;
/**
* This interface defines the API for serializing an object to a string.
*
* @author Rodion "rodde" Efremov
* @version 1.6
* @param <E> the element type.
*/
@FunctionalInterface
public interface StringSerializer<E> {
/**
* Returns the textual representation of the input object.
*
* @param element the object to serialize.
* @return the textual representation of the input object.
*/
public String serialize(E element);
/**
* Serializes all the objects. Each object should serialize to a single
* line, as the deserialization routine assumes that each line encodes
* entirely a single object.
*
* @param <E> the actual object type.
* @param list the list of objects to serialize.
* @param serializer the object serializer.
* @return the string representation of the entire list.
* @throws IllegalArgumentException if the serialization string of an
* object contains a new line character.
*/
public static <E> String serialize(List<E> list,
StringSerializer<E> serializer) {
StringBuilder sb = new StringBuilder();
for (E element : list) {
String text = serializer.serialize(element);
if (text.contains("\n")) {
throw new IllegalArgumentException(
"The serialization string of an object contains a new line " +
"character.");
}
sb.append(text).append("\n");
}
return sb.toString();
}
}
StringDeserializer.java:
package net.coderodde.lists.serial;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* This interface defines the API for deserializing the elements from their
* textual representation and provides a method for deserializing the lists.
*
* @author Rodion "rodde" Efremov
* @version 1.6
* @param <E> the element type.
*/
@FunctionalInterface
public interface StringDeserializer<E> {
/**
* Deserializes an element from its textual representation.
*
* @param text the string representing the state of the object.
* @return the actual, deserialized object.
*/
public E deserialize(String text);
/**
* Deserializes the entire text <code>text</code> to the list of objects
* being encoded.
*
* @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,
StringDeserializer<E> deserializer) {
List<E> ret = new ArrayList<>();
Scanner scanner = new Scanner(text);
while (scanner.hasNextLine()) {
ret.add(deserializer.deserialize(scanner.nextLine()));
}
return ret;
}
}
Demo.java:
package net.coderodde.lists.serial;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
public class Demo {
public static void main(String[] args) {
// Create.
List<Integer> input = getRandomInts(100, new Random());
// Serialize.
String text = StringSerializer.serialize(input, (e) -> e.toString());
// Deserialize.
List<Integer> output =
StringDeserializer.deserialize(text,
(e) -> Integer.parseInt(e));
System.out.println("Input list size: " + input.size());
System.out.println("Output list size: " + output.size());
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?