Introduction
Filtering a map by its keys is a common requirement in Java, particularly when you need to extract a subset of the map that matches specific criteria. Whether you’re working with large datasets, need to clean up data, or simply want to focus on a particular subset of keys, filtering a map is an essential operation. Java 8 introduced the Stream API, which provides a powerful and concise way to filter maps based on keys or values. In this guide, we’ll explore how to filter a map by its keys using various approaches in Java 8.
Table of Contents
- Problem Statement
- Solution Steps
- Java Program
- Filtering a Map by Key Using Streams
- Filtering a Map by Key with a Custom Predicate
- Filtering a Map by Multiple Keys
- Advanced Considerations
- Conclusion
Problem Statement
The task is to create a Java program that:
- Accepts a map of key-value pairs.
- Filters the map based on specific key criteria.
- Outputs the filtered map.
Example 1:
- Input: Map
{1: "Apple", 2: "Banana", 3: "Orange"}, Filter:Key > 1 - Output: Filtered Map
{2: "Banana", 3: "Orange"}
Example 2:
- Input: Map
{"Apple": 10, "Banana": 20, "Orange": 30}, Filter:Keys starting with "B" - Output: Filtered Map
{"Banana": 20}
Solution Steps
- Create a Map: Start with an unsorted map of key-value pairs.
- Filter the Map by Key: Use the Stream API to filter the map based on specific key criteria.
- Display the Result: Print the filtered map.
Java Program
Filtering a Map by Key Using Streams
The most straightforward way to filter a map by its keys in Java 8 is by using the Stream API. This method involves converting the map’s entry set to a stream, applying a filter based on the key, and collecting the results into a new map.
import java.util.Map;
import java.util.stream.Collectors;
/**
* Java 8 - Filter a Map by Key Using Streams
* Author: https://www.rameshfadatare.com/
*/
public class FilterMapByKeyUsingStreams {
public static void main(String[] args) {
// Step 1: Create a map
Map<Integer, String> map = Map.of(
1, "Apple",
2, "Banana",
3, "Orange"
);
// Step 2: Filter the map by keys greater than 1
Map<Integer, String> filteredMap = map.entrySet()
.stream()
.filter(entry -> entry.getKey() > 1)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue
));
// Step 3: Display the result
System.out.println("Filtered Map: " + filteredMap);
}
}
Output
Filtered Map: {2=Banana, 3=Orange}
Explanation
- The
entrySet()method converts the map into a set of key-value pairs. - The
stream()method creates a stream from the entry set. - The
filter(entry -> entry.getKey() > 1)method filters the stream by keys greater than 1. - The filtered entries are then collected back into a map using
Collectors.toMap().
Filtering a Map by Key with a Custom Predicate
If you need to apply more complex filtering logic, you can define a custom predicate to filter the map by its keys.
import java.util.Map;
import java.util.stream.Collectors;
/**
* Java 8 - Filter a Map by Key with a Custom Predicate
* Author: https://www.rameshfadatare.com/
*/
public class FilterMapByKeyWithCustomPredicate {
public static void main(String[] args) {
// Step 1: Create a map
Map<String, Integer> map = Map.of(
"Apple", 10,
"Banana", 20,
"Orange", 30
);
// Step 2: Filter the map by keys that start with 'B'
Map<String, Integer> filteredMap = map.entrySet()
.stream()
.filter(entry -> entry.getKey().startsWith("B"))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue
));
// Step 3: Display the result
System.out.println("Filtered Map: " + filteredMap);
}
}
Output
Filtered Map: {Banana=20}
Explanation
- The custom predicate
entry -> entry.getKey().startsWith("B")filters the map to include only those entries where the key starts with the letter ‘B’. - The filtered entries are collected back into a map using
Collectors.toMap().
Filtering a Map by Multiple Keys
You can also filter a map to include only specific keys by using a set of allowed keys.
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Java 8 - Filter a Map by Multiple Keys
* Author: https://www.rameshfadatare.com/
*/
public class FilterMapByMultipleKeys {
public static void main(String[] args) {
// Step 1: Create a map
Map<Integer, String> map = Map.of(
1, "Apple",
2, "Banana",
3, "Orange",
4, "Grape"
);
// Step 2: Define the keys to keep
Set<Integer> keysToKeep = Set.of(1, 3);
// Step 3: Filter the map by the specified keys
Map<Integer, String> filteredMap = map.entrySet()
.stream()
.filter(entry -> keysToKeep.contains(entry.getKey()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue
));
// Step 4: Display the result
System.out.println("Filtered Map: " + filteredMap);
}
}
Output
Filtered Map: {1=Apple, 3=Orange}
Explanation
- The
Set.of(1, 3)creates a set of keys that should be included in the filtered map. - The
filter(entry -> keysToKeep.contains(entry.getKey()))method filters the map to include only those entries with keys in the set. - The filtered entries are collected back into a map using
Collectors.toMap().
Advanced Considerations
-
Null Keys: If your map contains
nullkeys, ensure your filter logic handles them appropriately to avoidNullPointerException. -
Performance Considerations: Filtering large maps using streams is generally efficient, but for performance-critical applications, consider the cost of stream operations, especially when using complex predicates.
-
Immutable Maps: If you need to ensure that the filtered map remains immutable, you can wrap it with
Collections.unmodifiableMap()after filtering.
Conclusion
This guide provides methods for filtering a map by its keys in Java 8, covering approaches with the Stream API and custom predicates. Filtering maps by key is a common requirement in many applications, whether you’re narrowing down data, cleaning up datasets, or focusing on specific keys. Java 8 provides powerful tools to perform this task efficiently and flexibly. Depending on your specific use case, you can choose the method that best fits your needs for filtering maps in Java.