Definition
- Formatting map: the function concatenates or formats multiple fields of each element into a single display string.
- Lambda required: because the function reads two getters, it cannot be a single method reference.
String.formatis cleaner for complex templates; plain+is fine for simple two-field labels.- Null guard: substitute a default like
"Unknown"for missing fields to prevent the literal wordnullin output. - Reuse tip: extract the format into a
toLabel()method, then useEmployee::toLabelas a method reference.
The HR clerk at the National Bank of India is making a seating-plan list where each line reads like "Rajesh - Loans". She writes the name, a dash, then the department for every person. map building a formatted string is exactly that line-by-line labelling.
Understanding the Concepts
What does mapping to a formatted string do?
The map function builds a string from two fields, for example e -> e.getName() + " - " + e.getDepartment(), producing a label like "Rajesh - Loans". Each employee yields exactly one label, so it is one-to-one, and the stream's element type becomes String.
How do you create formatted labels?
package com.bank.hr;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
public class EmployeeLabels {
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> labels = staff.stream()
.map(e -> e.getName() + " - " + e.getDepartment())
.collect(Collectors.toList());
labels.forEach(System.out::println);
}
}
Rajesh - Loans
Priya - IT
Amit - Finance
How is concatenation different from String.format?
| Approach | When to use | Performance |
|---|---|---|
| name + " - " + dept | Simple two-field labels | Slightly faster |
| String.format("%s - %s", name, dept) | Complex templates, padding, alignment | Slower, more readable |
| "%s - %s".formatted(name, dept) | Java 15+ shorthand for String.format | Same as format |
// String.format for richer templates
List<String> formatted = staff.stream()
.map(e -> String.format("%-10s | %s", e.getName(), e.getDepartment()))
.collect(Collectors.toList());
Rajesh | Loans
Priya | IT
Amit | Finance
What are common mistakes?
Mistake: a null department makes the label show "Rajesh - null", which looks broken in a report.
// WRONG: null department prints "Rajesh - null"
String label = "Rajesh" + " - " + null; // "Rajesh - null"
// CORRECT: guard with a default
List<String> safe = staff.stream()
.map(e -> e.getName() + " - " +
(e.getDepartment() != null ? e.getDepartment() : "Unassigned"))
.collect(Collectors.toList());
What about extracting the format into a method?
When the label format is reused across the application, extract it into a method on the domain object and use a clean method reference.
public class Employee {
// ... fields, constructor, getters ...
public String toLabel() {
return name + " - " + department;
}
}
// Clean method reference in the stream
List<String> labels = staff.stream()
.map(Employee::toLabel)
.collect(Collectors.toList());
This keeps the formatting in one place and makes the stream read declaratively.
What about including salary in the label?
List<String> richLabels = staff.stream()
.map(e -> String.format("%s (%s) - Rs. %s",
e.getName(), e.getDepartment(),
e.getSalary().toPlainString()))
.collect(Collectors.toList());
Rajesh (Loans) - Rs. 95000
Priya (IT) - Rs. 120000
Amit (Finance) - Rs. 85000
What should a senior engineer know?
- For simple two-field labels, plain concatenation is perfectly fine and marginally faster.
- As the template grows,
String.formator Java 15+formattedkeeps the code readable. - Moving the format to a
toLabel()method on the entity makes it testable and reusable. - Be defensive about null fields; a null in concatenation silently becomes the string "null".
What are common interview follow-up questions?
- "Can you use a method reference here?" Only if the format is extracted to a single-argument method on the object.
- "When is String.format better than +?" When the template has padding, alignment, or many fields.
- "What happens if a field is null?" Concatenation silently turns it into the string "null".
Visual Overview
Employee("Rajesh", "Loans", 95000)
│
│ map(e -> e.getName() + " - " + e.getDepartment())
▼
String: "Rajesh - Loans"
Employee("Priya", "IT", 120000)
│
│ map(e -> ...)
▼
String: "Priya - IT"
Collected → List<String>
["Rajesh - Loans", "Priya - IT", "Amit - Finance"]
Key Takeaway
To build a readable label out of several fields I use map with a function that formats those fields into one string. Here each employee was mapped to a string combining its name, a dash, and its department, producing a label like "Rajesh - Loans", one per employee, collected into a list.
In my banking project at the National Bank of India this was a seating plan for a town-hall meeting. I put the formatting in a toLabel() method on the employee itself so the stream could use a clean method reference, and the format lived in exactly one place.
I always guard against null fields, because in Java concatenation silently turns null into the string "null", which looks broken in a printed report. For a simple two-field label, plain concatenation is fine; as the template grows I switch to String.format for readability.
Remember one sentence: map(e -> name + " - " + dept) builds a formatted label per element, and extracting the format to a method keeps it testable and reusable.
---