Info
In this guide we will parse an array list of hash maps into CSV, JSON and XML. The core concepts can be applied to parsing pretty much anything.CSV ##
Example for data in the CSV format:
1name,surname,age
2john,doe,45
3jan,doe,35
Tabular presentation:
index | name | surname | age |
---|---|---|---|
0 | john | doe | 45 |
1 | jan | doe | 35 |
Parsing values separated by comma is by far the easiest of the three encodings in this guide. Keep the separator in mind (here ,
, but could be any of: ;
, |
, :
or \t
) and check for a header row.
To keep this guide simple we hard-code the header keys and will not parse them dynamically:
Decoding ###
To convert a data from CSV to Hash maps in a array list we will first read a file (data.csv
) with the above content.
1import java.io.BufferedReader;
2import java.io.FileReader;
3import java.util.ArrayList;
4import java.util.HashMap;
5
6public class Main {
7 public static void main(String[] args) {
8 ArrayList<HashMap<String, String>> result = new ArrayList<>();
9 try{
10 // open the 'data.csv' file and create a reader
11 FileReader fileReader = new FileReader("data.csv");
12 // pass the reader to a buffered reader
13 BufferedReader bufferedReader = new BufferedReader(fileReader);
14
15 bufferedReader
16 // loop over the lines using the .lines() method
17 // which returns a stream
18 .lines()
19 // skip the header line
20 .skip(1)
21 // iterate over each line
22 .forEach(l -> {
23 // allocate a new hash map
24 HashMap<String, String> temp = new HashMap<>();
25
26 // split the line via its separator
27 String[] splitLine = l.split(",");
28 // assign the values to the know keys
29 temp.put("name", splitLine[0]);
30 temp.put("surname", splitLine[1]);
31 temp.put("age", splitLine[2]);
32
33 // add the hash map to the result list
34 result.add(temp);
35 });
36 } catch (Exception e){
37 // prints out if file cant be found or read
38 e.printStackTrace();
39 }
40
41 // print all hash maps in the list
42 result.forEach(System.out::println);
43 }
44}
Running the above yields the following result:
1{surname=doe, name=john, age=45}
2{surname=doe, name=jan, age=35}
Encoding ###
Encoding to csv is also very simple, instantiate a StringBuilder
, append the header and after that append each line:
1import java.io.BufferedReader;
2import java.io.FileReader;
3import java.util.ArrayList;
4import java.util.HashMap;
5
6public class Main {
7 public static void main(String[] args) {
8 ArrayList<HashMap<String, String>> result = new ArrayList<>();
9 try{
10 // open the 'data.csv' file and create a reader
11 FileReader fileReader = new FileReader("data.csv");
12 // pass the reader to a buffered reader
13 BufferedReader bufferedReader = new BufferedReader(fileReader);
14
15 bufferedReader
16 // loop over the lines using the .lines() method
17 // which returns a stream
18 .lines()
19 // skip the header line
20 .skip(1)
21 // iterate over each line
22 .forEach(l -> {
23 // allocate a new hash map
24 HashMap<String, String> temp = new HashMap<>();
25
26 // split the line via its separator
27 String[] splitLine = l.split(",");
28 // assign the values to the know keys
29 temp.put("name", splitLine[0]);
30 temp.put("surname", splitLine[1]);
31 temp.put("age", splitLine[2]);
32
33 // add the hash map to the result list
34 result.add(temp);
35 });
36 } catch (Exception e){
37 // prints out if the csv is invalid or file cant be found / read
38 e.printStackTrace();
39 }
40
41 // print all hash maps in the list
42 result.forEach(System.out::println);
43
44 StringBuilder stringBuilder = new StringBuilder();
45
46 // append the header row + the line separator of the system
47 stringBuilder
48 .append("name,surname,age")
49 .append(System.lineSeparator());
50
51 // loop over each line
52 result.forEach(e -> {
53 // create the row by getting the values from the current hash map
54 String formattedRow = String.format("%s,%s,%s,%s",
55 e.get("name"),
56 e.get("surname"),
57 e.get("age"),
58 System.lineSeparator());
59 // add the new row to the string builder
60 stringBuilder.append(formattedRow);
61 });
62
63 System.out.println(stringBuilder);
64 }
65}
Running the above yields the following result:
1{surname=doe, name=john, age=45}
2{surname=doe, name=jan, age=35}
3name,surname,age
4john,doe,45
5jan,doe,35
As expected, first the two decoded rows, afterwards the encoded representation as csv with the header row.
XML ##
XML is a somewhat outdated data exchange format, but especially people around java use it for configurations and data storage. The format is a lot more verbose, especially compared to csv.
Example for data in the XML format:
1<?xml version="1.0" encoding="UTF-8"?>
2<root>
3 <person>
4 <name>John</name>
5 <surname>Doe</surname>
6 <age>45</age>
7 </person>
8 <person>
9 <name>Jan</name>
10 <surname>Doe</surname>
11 <age>35</age>
12 </person>
13</root>
Decoding ###
Parsing XML requires a lot of boilerplate in Java so be prepared. I copied the above XML to a data.xml
file.
1import org.w3c.dom.Document;
2import org.w3c.dom.Element;
3import org.w3c.dom.Node;
4import org.w3c.dom.NodeList;
5
6import javax.xml.parsers.DocumentBuilder;
7import javax.xml.parsers.DocumentBuilderFactory;
8import java.util.ArrayList;
9import java.util.HashMap;
10
11public class Main {
12 public static void main(String[] args) {
13 // result list which contains all parsed rows
14 ArrayList<HashMap<String, String>> result = new ArrayList<>();
15 try {
16 // create a factory
17 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
18 // use the above factory to get a document builder
19 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
20 // use the document builder to parse the xml in the file 'data.xml'
21 Document doc = documentBuilder.parse("data.xml");
22
23 // get the list of persons
24 NodeList personList = doc.getElementsByTagName("person");
25 // loop over the list of person
26 for (int i = 0; i < personList.getLength(); i++) {
27 // create a node out of the current item
28 Node item = personList.item(i);
29 // check if the node is an Element
30 if (item.getNodeType() == Node.ELEMENT_NODE) {
31 // new hash map to contain the values of the row
32 HashMap<String, String> temp = new HashMap<>();
33 // put all values for the keys into the above map
34 temp.put("name", ((Element) item)
35 .getElementsByTagName("name")
36 .item(0)
37 .getTextContent());
38
39 temp.put("surname", ((Element) item)
40 .getElementsByTagName("surname")
41 .item(0)
42 .getTextContent());
43
44 temp.put("age", ((Element) item)
45 .getElementsByTagName("age")
46 .item(0)
47 .getTextContent());
48
49 // add the row to the result list
50 result.add(tmap);
51 }
52 }
53 } catch (Exception e) {
54 // triggers if xml is invalid or the file cant be opened
55 e.printStackTrace();
56 }
57 // print the list
58 result.forEach(System.out::println);
59 }
60}
Running the above yields the following result:
1{surname=Doe, name=John, age=45}
2{surname=Doe, name=Jan, age=35}
Encoding ###
Converting the parsed data back into XML requires even more boilerplate so read the comments carefully:
1import org.w3c.dom.Document;
2import org.w3c.dom.Element;
3import org.w3c.dom.Node;
4import org.w3c.dom.NodeList;
5
6import javax.xml.parsers.DocumentBuilder;
7import javax.xml.parsers.DocumentBuilderFactory;
8import javax.xml.transform.OutputKeys;
9import javax.xml.transform.Transformer;
10import javax.xml.transform.TransformerFactory;
11import javax.xml.transform.dom.DOMSource;
12import javax.xml.transform.stream.StreamResult;
13import java.io.StringWriter;
14import java.util.ArrayList;
15import java.util.HashMap;
16
17public class XML {
18 public static void main(String[] args) {
19 // result list which contains all parsed rows
20 ArrayList<HashMap<String, String>> result = new ArrayList<>();
21 try {
22 // create a factory
23 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
24 // use the above factory to get a document builder
25 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
26 // use the document builder to parse the xml in the file 'data.xml'
27 Document doc = documentBuilder.parse("data.xml");
28
29 // get the list of persons
30 NodeList personList = doc.getElementsByTagName("person");
31 // loop over the list of person
32 for (int i = 0; i < personList.getLength(); i++) {
33 // create a node out of the current item
34 Node item = personList.item(i);
35 // check if the node is an Element
36 if (item.getNodeType() == Node.ELEMENT_NODE) {
37 // new hash map to contain the values of the row
38 HashMap<String, String> temp = new HashMap<>();
39 // put all values for the keys into the above map
40 temp.put("name", ((Element) item)
41 .getElementsByTagName("name")
42 .item(0)
43 .getTextContent());
44
45 temp.put("surname", ((Element) item)
46 .getElementsByTagName("surname")
47 .item(0)
48 .getTextContent());
49
50 temp.put("age", ((Element) item)
51 .getElementsByTagName("age")
52 .item(0)
53 .getTextContent());
54
55 // add the row to the result list
56 result.add(tmap);
57 }
58 }
59 } catch (Exception e) {
60 // triggers if xml is invalid or the file cant be opened
61 e.printStackTrace();
62 }
63 // print the list
64 result.forEach(System.out::println);
65
66 try {
67 // create a factory
68 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
69 // use the factory to get a new document builder
70 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
71
72 // use the document builder to get a new document
73 Document doc = documentBuilder.newDocument();
74
75 // create the root element
76 Element rootElement = doc.createElement("root");
77 // append the root element to the document
78 doc.appendChild(rootElement);
79
80 // loop over the maps in the result list
81 for (HashMap<String, String> map : result) {
82 // create a person element
83 Element person = doc.createElement("person");
84 // add the person element to the root element
85 rootElement.appendChild(person);
86
87 // create elements and set their text content
88 // to the value stored in the hash map
89 Element name = doc.createElement("name");
90 name.setTextContent(map.get("name"));
91 person.appendChild(name);
92
93 Element surname = doc.createElement("surname");
94 surname.setTextContent(map.get("surname"));
95 person.appendChild(surname);
96
97 Element age = doc.createElement("age");
98 age.setTextContent(map.get("age"));
99 person.appendChild(age);
100 }
101
102 // get a new transformer factory
103 TransformerFactory transformerFactory = TransformerFactory.newInstance();
104 // use the factory to get a new Transformer
105 Transformer transformer = transformerFactory.newTransformer();
106
107 // instruct the transformer
108 // to add XML declaration at the top of the file
109 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
110 // instruct the transformer to indent the output
111 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
112
113 // get a new DOMSource from the document
114 DOMSource source = new DOMSource(doc);
115 // create a stringwriter to transform the source into
116 StringWriter stringWriter = new StringWriter();
117 transformer.transform(source, new StreamResult(stringWriter));
118
119 // print the output
120 System.out.println(stringWriter);
121 } catch (Exception e) {
122 e.printStackTrace();
123 }
124 }
125}
Running the above yields the following result:
1{surname=Doe, name=John, age=45}
2{surname=Doe, name=Jan, age=35}
3<root>
4 <person>
5 <name>John</name>
6 <surname>Doe</surname>
7 <age>45</age>
8 </person>
9 <person>
10 <name>Jan</name>
11 <surname>Doe</surname>
12 <age>35</age>
13 </person>
14</root>
JSON ##
Json is the de facto standard data exchange and configuration standard. The whole JavaScript and Typescript ecosystem uses JSON to configure tools and send + receive data from REST APIS.
Danger
To parse json we us the org.json library. I wont discuss package / library managment in depth here, but the repo includes a guide for adding the library to your project.
Adding org.json to your project using gradle: ####
- Add the following highlighted line to your
build.gradle
:
1plugins {
2 id 'java'
3}
4
5group 'org.example'
6version null
7
8repositories {
9 mavenCentral()
10}
11
12dependencies {
13 implementation group: 'org.json', name: 'json', version: '20211205'
14}
- Click on the green arrow next to the
dependencies
to download the dependency
Decoding ###
The example we want to parse into an ArrayList
of hash maps is the following:
1[
2 {
3 "name": "John",
4 "surname": "Doe",
5 "age": 45
6 },
7 {
8 "name": "Jan",
9 "surname": "Doe",
10 "age": 35
11 }
12]
Parsing a string to json is fairly easy while using the org.json library:
1import java.io.BufferedReader;
2import java.io.File;
3import java.io.FileReader;
4import java.util.ArrayList;
5import java.util.HashMap;
6import java.util.stream.Collectors;
7
8import org.json.*;
9
10public class Main {
11 public static void main(String[] args) {
12 ArrayList<HashMap<String, String>> result = new ArrayList<>();
13 try{
14 // create a new file
15 File file = new File("data.json");
16 FileReader fileReader = new FileReader(file);
17 // read file with bufferedReader for better perf
18 BufferedReader bufferedReader = new BufferedReader(fileReader);
19 // read the lines and join them by "\n"
20 String fileContent = bufferedReader.lines().collect(Collectors.joining("\n"));
21
22 // use org.json.JSONArray to parse the string to a json object
23 JSONArray jsonArray = new JSONArray(fileContent);
24 // loop over every object in the array
25 for(int i = 0; i < jsonArray.length(); i++){
26 // create a new json object for every entry in the array
27 JSONObject o = jsonArray.getJSONObject(i);
28
29 // hash map to store row values
30 HashMap<String, String> temp = new HashMap<>();
31 // add values to keys
32 temp.put("name", o.getString("name"));
33 temp.put("surname", o.getString("surname"));
34 temp.put("age", String.valueOf(o.getInt("age")));
35
36 // add row to result
37 result.add(temp);
38 }
39 } catch (Exception e){
40 e.printStackTrace();
41 }
42
43 result.forEach(System.out::println);
44 }
45}
The above results in the same output as the parsing for CSV and XML:
1{surname=Doe, name=John, age=45}
2{surname=Doe, name=Jan, age=35}
Encoding ###
Encoding java objects into json is so easy it can be done in one loc:
1import java.io.BufferedReader;
2import java.io.File;
3import java.io.FileReader;
4import java.util.ArrayList;
5import java.util.HashMap;
6import java.util.stream.Collectors;
7
8import org.json.*;
9
10public class Main {
11 public static void main(String[] args) {
12 ArrayList<HashMap<String, String>> result = new ArrayList<>();
13 try{
14 // create a new file
15 File file = new File("data.json");
16 FileReader fileReader = new FileReader(file);
17 // read file with bufferedReader for better perf
18 BufferedReader bufferedReader = new BufferedReader(fileReader);
19 // read the lines and join them by "\n"
20 String fileContent = bufferedReader
21 .lines()
22 .collect(Collectors.joining("\n"));
23
24 // use org.json.JSONArray to parse the string to a json object
25 JSONArray jsonArray = new JSONArray(fileContent);
26 // loop over every object in the array
27 for(int i = 0; i < jsonArray.length(); i++){
28 // create a new json object for every entry in the array
29 JSONObject o = jsonArray.getJSONObject(i);
30
31 // hash map to store row values
32 HashMap<String, String> temp = new HashMap<>();
33 // add values to keys
34 temp.put("name", o.getString("name"));
35 temp.put("surname", o.getString("surname"));
36 temp.put("age", String.valueOf(o.getInt("age")));
37
38 // add row to result
39 result.add(temp);
40 }
41 } catch (Exception e){
42 e.printStackTrace();
43 }
44
45 result.forEach(System.out::println);
46
47 System.out.println(new JSONArray(result).toString(4));
48 }
49}
The above results in:
1{surname=Doe, name=John, age=45}
2{surname=Doe, name=Jan, age=35}
3[
4 {
5 "name": "John",
6 "surname": "Doe",
7 "age": "45"
8 },
9 {
10 "name": "Jan",
11 "surname": "Doe",
12 "age": "35"
13 }
14]