...and what if the name contains two words with a blank in between??
Why do you need to invent your own format for serialization and de-serialization? why not use an industry standard like json, where you can utilize any of many libraries that can do the serialization and de-serialization. Do you need me to show you how?
EDIT:
OK, it turned out that using json is not as straightforward as I initially thought. Don't get me wrong, it is still better than custom format in the sense that it is bug-proof and supports edge cases like the one I described above.
The obstacle with json is that the key to every object and property has to be a String. So when the key is a user defined type (like Person
in your case) it didn’t get serialized properly - there is a need for a transitional data structure before the serialization to json can be performed.
So this is what I did: for each entry in your dictionary, I create a map that holds two entries: a "person" entry with the json String representation of the Person object, and a "pets" entry with the json String representation of the list of pets. So the final String to be serialized is actually a List
of Map
s.
To give you an idea: every map entry looks like this as json:
{
"person":{"name":"AISEC","age":12,"sex":"MALE"},
"pets":[
{"name":"Loo","age":12,"type":"Cat"},
{"name":"Kitty","age":4,"type":"Cat"}
]
}
The deserialization is simply the reverse operation.
I am using Jackson library as json parser and writer
This is the serialization method. it returns a String
that can be written to a file:
public String dictToJson(Map<Person, List<Pet>> map) throws IOException
{
ObjectMapper mapper = new ObjectMapper();
// serialized dictionary is list of maps
List<Map<String, String>> jsonDictionary = new ArrayList<>();
for (Map.Entry<Person, List<Pet>> mapEntry : map.entrySet()) {
// each map entry becomes its own map instance with two entries
Map<String, String> jsonEntry = new HashMap<>();
// write person key as "person" with json string represetation of person object
jsonEntry.put("person", mapper.writeValueAsString(mapEntry.getKey()));
// write pets value as "pets" key with json string represetation of pets list
jsonEntry.put("pets", mapper.writeValueAsString(mapEntry.getValue()));
jsonDictionary.add(jsonEntry);
}
return mapper.writeValueAsString(jsonDictionary);
}
The de-serialization method accpets String (whole content of file):
public Map<Person, List<Pet>> jsonToDict(String json) throws IOException
{
Map<Person, List<Pet>> map = new HashMap<>();
ObjectMapper mapper = new ObjectMapper();
// read json String into list of maps
List<Map<String, String>> jsonDictionary =
mapper.readValue(json, new TypeReference<List<Map<String, Object>>>(){});
// each list item is a map with two entries
for (Map<String, String> jsonEntry : jsonDictionary) {
map.put(
mapper.readValue(jsonEntry.get("person"), Person.class),
mapper.readValue(jsonEntry.get("pets"), new TypeReference<List<Pet>>(){}));
}
return map;
}
usage and test method:
public static void main(String[] args)
{
Map<Person, List<Pet>> map ; {
map = new HashMap<>();
map.put(new Person("JOHN", 10, "MALE"),
Arrays.asList(new Pet[]{new Pet("Spot", 3, "Dog")}));
map.put(new Person("AISEC", 12, "MALE"),
Arrays.asList(new Pet[]{new Pet("Loo", 12, "Cat"), new Pet("Kitty", 4, "Cat")}));
}
try {
// serialize map into String
String serializedDict = dictToJson(map);
// write to file ...
System.out.println(serializedDict);
map.clear();
// de-serialize from String to map
map = jsonToDict(serializedDict);
// check if map was built ok
System.out.println(dictToJson(map));
} catch (Exception e) {
e.printStackTrace();
}
}