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]