Back to Stream: map & Transform
Q18Question 18 of 34

Convert a List<Employee> back into a List<String> of CSV rows (reverse of the above)

Key Concepts
  • map() can serialise each object into a CSV row by joining its fields with commas
  • Use BigDecimal.toPlainString() for salary to avoid scientific notation on very large numbers
  • Serialisation and parsing should be symmetric: a round-trip test catches formatting bugs
  • If any field could contain the delimiter, use proper CSV quoting and escaping
  • The mapping function is one-to-one: each Employee becomes exactly one CSV line
  • For file output, write the list with Files.write or BufferedWriter after collecting

Definition

`map` can serialise each object into a CSV row by joining its fields with commas.
  • Serialising map: turns each Employee back into a single comma-separated string.
  • toPlainString() on BigDecimal avoids scientific notation for very large numbers.
  • Round-trip symmetry: parse then serialise should reproduce the original line, and vice versa.
  • Escaping: if a field could contain the delimiter, use proper CSV quoting or a library.
  • File output: collect the CSV lines into a list, then write with Files.write() or BufferedWriter.

The clerk at the National Bank of India now has filled employee forms and must send them back out as plain text, one line per person like "Rajesh,Loans,95000". She reads each form and writes its fields on a line separated by commas.

Understanding the Concepts

How do you serialise employees back to CSV?

The mapping function takes an Employee and returns one CSV string. The simplest form joins the fields directly.

JAVA
package com.bank.hr;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

public class EmployeeToCsv {
    public static void main(String[] args) {
        List<Employee> staff = List.of(
            new Employee("Rajesh",  "Loans",   new BigDecimal("95000")),
            new Employee("Priya",   "IT",      new BigDecimal("120000")),
            new Employee("Amit",    "Finance", new BigDecimal("85000")));

        List<String> csvLines = staff.stream()
            .map(e -> e.getName() + "," + e.getDepartment() + ","
                    + e.getSalary().toPlainString())
            .collect(Collectors.toList());

        csvLines.forEach(System.out::println);
    }
}
TEXT
Rajesh,Loans,95000
Priya,IT,120000
Amit,Finance,85000

Why use toPlainString for BigDecimal?

BigDecimal.toString() can produce scientific notation for very large or very small values, for example 1.2E+8 instead of 120000000. toPlainString() always produces the full decimal form.

JAVA
BigDecimal big = new BigDecimal("120000000");
System.out.println(big.toString());        // might be 1.2E+8
System.out.println(big.toPlainString());    // always 120000000

How do you write the CSV to a file?

JAVA
import java.nio.file.Files;
import java.nio.file.Path;

String header = "name,department,salary";
List<String> allLines = new java.util.ArrayList<>();
allLines.add(header);
allLines.addAll(csvLines);

Files.write(Path.of("employees.csv"), allLines);
System.out.println("Written " + csvLines.size() + " data rows.");

What is a round-trip test and why does it matter?

DIAGRAM
| Direction | Test |
|---|---|
| Parse then serialise | Original CSV line → Employee → CSV line (should match original) |
| Serialise then parse | Employee → CSV line → Employee (should match original) |
JAVA
// Round-trip test
String original = "Rajesh,Loans,95000";
Employee parsed = parseLine(original);
String serialised = toCSV(parsed);
assert original.equals(serialised) : "Round-trip failed!";

A round-trip property is the quickest way to catch a formatting or escaping bug before it corrupts an export.

What are common mistakes?

Mistake: not escaping fields that contain the delimiter.

JAVA
// WRONG: department "Sales, North" breaks the row
Employee e = new Employee("Rajesh", "Sales, North", new BigDecimal("95000"));
String csv = e.getName() + "," + e.getDepartment() + "," + e.getSalary();
// "Rajesh,Sales, North,95000" → 4 columns instead of 3!

// CORRECT: quote fields that contain the delimiter
String safeCsv = e.getName() + ",\"" + e.getDepartment() + "\"," + e.getSalary();
// "Rajesh,\"Sales, North\",95000" → correct 3 columns

For anything beyond trivial data, use a proper CSV library like OpenCSV.

What about using String.join?

JAVA
// Cleaner alternative with String.join
List<String> csvLines = staff.stream()
    .map(e -> String.join(",",
        e.getName(), e.getDepartment(), e.getSalary().toPlainString()))
    .collect(Collectors.toList());

What should a senior engineer know?

  • Serialisation and parsing must be symmetric and tested together.
  • For money, use toPlainString() to avoid scientific notation.
  • For data not guaranteed delimiter-free, use a proper CSV library with quoting and escaping.
  • The source list is never mutated; map produces a new stream of CSV strings.

What are common interview follow-up questions?

  • "How do you handle fields with commas?" Use CSV quoting or a library.
  • "How do you write the result to a file?" Use Files.write(path, lines).
  • "What is a round-trip test?" Parsing and serialising should be inverse operations.

Visual Overview

DIAGRAM
  Employee("Rajesh", "Loans", 95000)
       │
       │  map(e -> name + "," + dept + "," + salary.toPlainString())
       ▼
  String: "Rajesh,Loans,95000"

  Employee("Priya", "IT", 120000)
       │
       │  map(e -> ...)
       ▼
  String: "Priya,IT,120000"

  Collected → List<String>
  ["Rajesh,Loans,95000", "Priya,IT,120000", "Amit,Finance,85000"]
       │
       │  Files.write(path, lines)
       ▼
  employees.csv on disk

Key Takeaway

To serialise structured objects back into CSV I use a map whose function joins each object's fields with commas, so the stream goes from employees to strings, one row per employee. For the salary I render it with toPlainString() so the output never slips into scientific notation.

In my banking project at the National Bank of India this was the nightly export to a partner system that only accepts plain CSV. It is the exact reverse of the import.

The most important quality check is the round-trip test: parsing a line and serialising it again should reproduce the original, and serialising an object and parsing it back should reproduce the original object. For data that is not guaranteed delimiter-free I use a proper CSV library for quoting and escaping.

Remember one sentence: map(e -> name + "," + dept + "," + salary.toPlainString()) serialises each employee to a CSV row, and a round-trip test verifies correctness.

---

Share
Use ← → arrow keys to navigate