Java 8 – Filter a Map by Key

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

  1. Create a Map: Start with an unsorted map of key-value pairs.
  2. Filter the Map by Key: Use the Stream API to filter the map based on specific key criteria.
  3. 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 null keys, ensure your filter logic handles them appropriately to avoid NullPointerException.

  • 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.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top