Definition
- map.entrySet().stream() creates a
Stream.> - filter(e -> e.getValue() > 100) keeps entries whose value exceeds 100.
- toMap(Entry::getKey, Entry::getValue) rebuilds a map from the surviving entries.
- The original map is unchanged: streams never mutate the source.
- For in-place removal, use
entrySet().removeIf(predicate)instead.
Priya at the National Bank of India has a product price list and wants only the premium products costing more than one hundred. She scans each line, keeps the expensive ones, and writes a new, shorter list. The original list stays intact.
Understanding the Concepts
How do you filter a map by value?
A map has no stream() method. You call entrySet().stream() to get a stream of Map.Entry objects, filter on the value, and collect back into a map.
package com.bank.products;
import java.util.*;
import java.util.stream.Collectors;
public class FilterMapByValue {
public static void main(String[] args) {
Map<String, Integer> productPrices = Map.of(
"Savings Account", 0,
"Current Account", 50,
"Premium Account", 200,
"Gold Locker", 150,
"Basic Locker", 75
);
Map<String, Integer> premium = productPrices.entrySet().stream()
.filter(e -> e.getValue() > 100)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue));
System.out.println("Premium products: " + premium);
}
}
Premium products: {Premium Account=200, Gold Locker=150}
Can you filter on both key and value?
Yes. The predicate has access to the full entry.
// Keep lockers priced above 100
Map<String, Integer> expensiveLockers = productPrices.entrySet().stream()
.filter(e -> e.getKey().contains("Locker")
&& e.getValue() > 100)
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue));
How do you filter in place instead of creating a new map?
// In-place removal: modifies the original map
Map<String, Integer> mutable = new HashMap<>(productPrices);
mutable.entrySet().removeIf(e -> e.getValue() <= 100);
System.out.println(mutable);
// {Premium Account=200, Gold Locker=150}
| Approach | Original map | Creates new map? |
|---|---|---|
| stream + filter + toMap | Unchanged | Yes |
| entrySet().removeIf() | Modified | No |
How do you preserve insertion order in the result?
Map<String, Integer> ordered = productPrices.entrySet().stream()
.filter(e -> e.getValue() > 100)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(a, b) -> a,
LinkedHashMap::new));
What are common mistakes?
Mistake: calling stream() on the map directly.
// WRONG: Map has no stream() method
productPrices.stream() // compile error!
// CORRECT: stream the entrySet
productPrices.entrySet().stream()
Mistake: forgetting that > 100 excludes exactly 100.
// This excludes products priced at exactly 100
filter(e -> e.getValue() > 100)
// This includes products priced at exactly 100
filter(e -> e.getValue() >= 100)
What should a senior engineer know?
- Keys in the source map are unique, so the rebuilt toMap needs no merge function.
- Choosing between a new map and in-place removal is a decision about immutability and whether the source should change.
- For concurrent maps, use ConcurrentHashMap.entrySet().removeIf() for thread-safe in-place filtering.
- The filter predicate is a Predicate
, so you can compose it with and(), or(), negate().
What are common interview follow-up questions?
- "How do you filter a map by key?" Same pattern: filter(e -> e.getKey().startsWith("Premium")).
- "How do you count how many entries survive?" Use count() instead of collect.
- "How do you get just the keys or values after filtering?" Collect into a List with mapping.Visual Overview
Map<String, Integer>
┌────────────────────────────┐
│ Savings Account → 0 │
│ Current Account → 50 │
│ Premium Account → 200 │
│ Gold Locker → 150 │
│ Basic Locker → 75 │
└────────────────────────────┘
│
│ entrySet().stream()
│ .filter(value > 100)
▼
Surviving entries:
Premium Account → 200 ✓
Gold Locker → 150 ✓
│
│ toMap(key, value)
▼
Filtered Map<String, Integer>
┌────────────────────────────┐
│ Premium Account → 200 │
│ Gold Locker → 150 │
└────────────────────────────┘
Key Takeaway
A map has no stream() method, so to filter it you stream its entrySet, apply a filter on the value (or key, or both), and collect the survivors back into a new map with toMap. The original map is left untouched because streams never mutate their source.
At the National Bank of India, this produced a premium product view showing only products whose fee exceeds the threshold. Pay attention to boundary precision: greater-than excludes the exact threshold, while greater-than-or-equal includes it.
Choose between producing a new map (stream + toMap) and mutating the original (entrySet().removeIf()) based on whether the source map is allowed to change. For ordered output, supply a LinkedHashMap.
Remember one sentence: stream entrySet, filter by value, collect with toMap to produce a filtered copy, and the original map stays unchanged.
---