Definition
- filter(n -> n > threshold) keeps elements strictly above the threshold.
- map(String::valueOf) converts each surviving Integer to its decimal string.
- Filter before map avoids wasted conversions on discarded elements.
- Null safety: filter nulls first; unboxing null Integer to int throws NullPointerException.
- Threshold semantics: decide strict (>) or inclusive (>=) based on the business rule.
Priya at the National Bank of India keeps only transaction amounts above a reporting cutoff and renders them as text for a display panel that shows high-value transactions.
Understanding the Concepts
What does this question ask?
The interviewer wants filter-then-map: filter integers above a threshold, then convert to strings. This tests operation order, the filter-then-map pattern, and null handling.
How do you filter and convert?
package com.bank.service;
import java.util.List;
public class FilterThenMap {
public static void main(String[] args) {
List<Integer> amounts = List.of(
25000, 50000, 75000, 100000, 150000, 200000);
int threshold = 50000;
List<String> highValue = amounts.stream()
.filter(n -> n > threshold)
.map(String::valueOf)
.toList();
System.out.println("Above Rs." + threshold + ": " + highValue);
}
}
Above Rs.50000: [75000, 100000, 150000, 200000]
Why filter before map?
// GOOD: filter first, map only survivors
amounts.stream()
.filter(n -> n > threshold) // shrinks the stream
.map(String::valueOf) // converts only what passed
.toList();
// BAD: map everything, then filter on strings
amounts.stream()
.map(String::valueOf) // converts ALL elements
.filter(s -> Integer.parseInt(s) > threshold) // parses back!
.toList();
Filtering first avoids unnecessary work. Place the cheap, selective operation before the expensive transformation.
How do you handle nulls in the list?
import java.util.Arrays;
import java.util.Objects;
List<Integer> withNulls = Arrays.asList(25000, null, 75000, null);
// WRONG: NullPointerException when unboxing null to int
// withNulls.stream().filter(n -> n > 50000)...
// CORRECT: filter nulls first
List<String> safe = withNulls.stream()
.filter(Objects::nonNull)
.filter(n -> n > 50000)
.map(String::valueOf)
.toList();
How do you format the output as currency?
import java.text.NumberFormat;
import java.util.Locale;
NumberFormat inr = NumberFormat.getCurrencyInstance(
new Locale("en", "IN"));
List<String> formatted = amounts.stream()
.filter(n -> n > threshold)
.map(n -> inr.format(n))
.toList();
System.out.println(formatted);
How is filter-then-map different from map-then-filter?
| Order | Behavior | Efficiency |
|---|---|---|
| filter then map | Converts only retained elements | Better |
| map then filter | Converts all, then discards some | Wasteful |
Always place the more selective operation first in the pipeline.
What about using mapToInt for primitive operations?
// If you need the count of values above threshold
long count = amounts.stream()
.mapToInt(Integer::intValue)
.filter(n -> n > threshold)
.count();
What are common mistakes?
Mistake: using == instead of > for the threshold.
// WRONG: keeps only values EQUAL to threshold
.filter(n -> n == threshold)
// CORRECT: keeps values ABOVE threshold
.filter(n -> n > threshold)
Mistake: comparing boxed Integers with == instead of equals.
// WRONG for large values: == compares references
Integer a = 1000;
Integer b = 1000;
System.out.println(a == b); // false (different objects)
System.out.println(a.equals(b)); // true
// For primitives in filter lambdas, unboxing handles this correctly:
// n -> n > threshold unboxes both sides
What are common interview follow-up questions?
- "How do you convert to a comma-separated string?" Chain .collect(Collectors.joining(", ")).
- "How do you map to a different format?" Use map with a formatting lambda.
- "How do you collect both the passing and failing elements?" Use partitioningBy.
Visual Overview
List: [25000, 50000, 75000, 100000, 150000, 200000]
│
│ .filter(n -> n > 50000)
▼
[75000, 100000, 150000, 200000] (4 elements pass)
│
│ .map(String::valueOf) (converts only 4 elements)
▼
["75000", "100000", "150000", "200000"]
Key: filter BEFORE map = fewer conversions
Key Takeaway
Filtering numbers above a threshold and converting to strings uses the filter-then-map pattern: filter first to shrink the stream, then map only the survivors to strings. This avoids wasted conversions on values that will be discarded.
Decide whether the threshold is strict (>) or inclusive (>=) based on the business rule, and filter nulls explicitly before the comparison to avoid NullPointerException from unboxing. At the National Bank of India, Priya used this for a display panel showing only high-value transaction amounts rendered as text.
This filter-then-map shape is one of the most common pipelines, and placing the cheap, selective filter first is a simple but real optimization.
Remember one sentence: filter before map so the expensive conversion runs only on retained elements, and always filter nulls before unboxing comparisons.
---