java
43 lines · 7 steps
Parsing a CSV into typed objects in Java
A header-driven CSV parser maps column names to indices so rows become Employee objects regardless of column order.
Explained by
highlit
1public List<Employee> parseEmployees(Path csvPath) throws IOException {
2 List<Employee> employees = new ArrayList<>();
3
4 try (BufferedReader reader = Files.newBufferedReader(csvPath, StandardCharsets.UTF_8)) {
5 String headerLine = reader.readLine();
6 if (headerLine == null) {
7 return employees;
8 }
9
10 String[] headers = splitCsvLine(headerLine);
11 Map<String, Integer> columns = new HashMap<>();
12 for (int i = 0; i < headers.length; i++) {
13 columns.put(headers[i].trim().toLowerCase(), i);
14 }
15
16 String line;
17 int lineNumber = 1;
18 while ((line = reader.readLine()) != null) {
19 lineNumber++;
20 if (line.isBlank()) {
21 continue;
22 }
23
24 String[] fields = splitCsvLine(line);
25 if (fields.length < columns.size()) {
26 throw new IllegalStateException("Malformed row at line " + lineNumber);
27 }
28
29 Employee employee = new Employee(
30 fields[columns.get("id")].trim(),
31 fields[columns.get("name")].trim(),
32 new BigDecimal(fields[columns.get("salary")].trim())
33 );
34 employees.add(employee);
35 }
36 }
37
38 return employees;
39}
40
41private String[] splitCsvLine(String line) {
42 return line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
43}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Mapping header names to indices decouples parsing from a fixed column order.
- 2try-with-resources guarantees the reader closes even when parsing throws.
- 3Validating field counts before access turns silent corruption into a clear, located error.
Related explainers
rust
use once_cell::sync::Lazy; use regex::Regex; static NON_ALPHANUMERIC: Lazy<Regex> = Lazy::new(|| Regex::new(r"[^a-z0-9]+").unwrap());
Building URL slugs in Rust
string-processing
regex
transliteration
Intermediate
8 steps
java
public final class CaseConverter { private static final Pattern CAMEL_BOUNDARY = Pattern.compile("([a-z0-9])([A-Z])|([A-Z]+)([A-Z][a-z])");
Converting camelCase to snake_case in Java
regex
string-manipulation
utility-class
Intermediate
7 steps
java
@Component public class RegionCacheWarmer implements SmartInitializingSingleton { private static final Logger log = LoggerFactory.getLogger(RegionCacheWarmer.class);
Warming a Spring cache at startup
caching
startup-hook
dependency-injection
Intermediate
7 steps
python
import pandas as pd import numpy as np
Cleaning a customer DataFrame with pandas
data-cleaning
regex
normalization
Intermediate
9 steps
java
public final class EmailNormalizer { private static final Pattern EMAIL_PATTERN = Pattern.compile( "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$"
Normalizing email addresses in Java
validation
regex
normalization
Intermediate
8 steps
java
@RestController @RequestMapping("/api/products") @RequiredArgsConstructor public class ProductBatchController {
Batch JSON Merge Patch in Spring
json-merge-patch
rest-api
partial-update
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/parsing-a-csv-into-typed-objects-in-java-explained-java-f26d/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.