Java 8 – Filter a Map by keys and values

In this guide, we will see how to use Stream’s filter() method to filter a Map by keys and Values. With Java 8, you can convert a Map.entrySet() into a stream, followed by a filter() and collect() it. While filtering the Map we can provide logical operators like AND , OR to check condition on keys and values. Consider the following dummy data set for developing these examples.

public static Map<String, String> getStudentList() {
	Map<String, String> studentByRoll = new HashMap<>();
	studentByRoll.put("CS-101", "Ailsa");
	studentByRoll.put("CS-104", "Amelia");
	studentByRoll.put("CS-105", "Annabel");
	studentByRoll.put("ME-102", "Alice");
	studentByRoll.put("ME-103", "Anwen");
	studentByRoll.put("ME-109", "Arabella");
	studentByRoll.put("ME-104", "Aariyeh");
	studentByRoll.put("EE-103", "Bretton");
	studentByRoll.put("EE-109", "Bleiz");
	studentByRoll.put("EE-107", "Cameleac");
	return studentByRoll;
}

 

Example 1 : Filter a Map by key and Collect the result in another Map. Like Filter all Students from Computer Science (CS) department.

Map<String, String> csStudents = studentByRoll.entrySet().stream()
	.filter(s -> s.getKey().startsWith("CS"))
	.collect(Collectors.toMap(e -> e.getKey(), e -> String.valueOf(e.getValue())));

 

Example 2 : Filter a Map by more than one key and Collect the result in another Map.Like Filter all Students from Computer Science (CS) and Mechanical (ME) department.

Map<String, String> csAndMeStudents = studentByRoll.entrySet().stream()
	.filter(s -> s.getKey().startsWith("CS") || s.getKey().startsWith("ME"))
	.collect(Collectors.toMap(e -> e.getKey(), e -> String.valueOf(e.getValue())));

 

Example 3 : Filter a Map by key and value and Collect the result in another Map. Like Filter all Students from Electronics department (EE) and and whose name starts with B.

Map<String, String> eeStudents = studentByRoll.entrySet().stream()
	.filter(s -> s.getKey().startsWith("EE"))
	.filter(s -> s.getValue().startsWith("B"))
	.collect(Collectors.toMap(e -> e.getKey(), e -> String.valueOf(e.getValue())));

 

Example 4: We can also search by key or value in a Map. And Collect the result as a String or Comma separated String. Consider te following examples where we are going to search a Student by roll number or we can search all the Students from a department and Collect the result as a Comma separated String.

// Find a Student By rollNo
// Map -> Stream -> Filter -> String
String studentName = studentByRoll.entrySet().stream()
		.filter(map -> "CS-104".equals(map.getKey()))
		.map(map -> map.getValue()).collect(Collectors.joining());
System.out.println("Roll: CS-104 , Name :" + studentName);

/**
 * Filter more values.Like Filter all Students from Electronics
 * department (EE) and and whose name starts with B and Collect to a
 * comma separated String
 */
studentName = studentByRoll.entrySet().stream().filter(x -> {
	if (x.getKey().startsWith("EE") && x.getValue().startsWith("B")) {
		return true;
	}
	return false;
}).map(map -> map.getValue()).collect(Collectors.joining(","));
System.out.println(studentName);

 

Now All the above Example can be aggregated together in a Single executable program as :

package com.tuturself.stream;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class MapFilterTest {

  public static void main(String[] args) {

	/**
	 * Following is our dummy data, a group of Students by Roll Number
	 */
	Map<String, String> studentByRoll = getStudentList();

	/**
	 * Filter a Map by key and Collect the result in another Map.Like Filter
	 * all Students from Computer Science (CS) department
	 */
	Map<String, String> csStudents = studentByRoll.entrySet().stream()
			.filter(s -> s.getKey().startsWith("CS"))
			.collect(Collectors.toMap(e -> e.getKey(), e -> String.valueOf(e.getValue())));
	prettyPrint("Filter a Map by key", csStudents);

	/**
	 * Filter a Map by more than one key and Collect the result in another
	 * Map.Like Filter all Students from Computer Science (CS) and
	 * Mechanical (ME) department
	 */
	Map<String, String> csAndMeStudents = studentByRoll.entrySet().stream()
			.filter(s -> s.getKey().startsWith("CS") || s.getKey().startsWith("ME"))
			.collect(Collectors.toMap(e -> e.getKey(), e -> String.valueOf(e.getValue())));
	prettyPrint("Filter a Map by more than one key", csAndMeStudents);

	/**
	 * Filter a Map by key and value and Collect the result in another
	 * Map.Like Filter all Students from Electronics department (EE) and and
	 * whose name starts with B
	 */
	Map<String, String> eeStudents = studentByRoll.entrySet().stream()
			.filter(s -> s.getKey().startsWith("EE"))
			.filter(s -> s.getValue().startsWith("B"))
			.collect(Collectors.toMap(e -> e.getKey(), e -> String.valueOf(e.getValue())));
	prettyPrint("Filter a Map by key and value", eeStudents);

	// Find a Student By rollNo
	// Map -> Stream -> Filter -> String
	String studentName = studentByRoll.entrySet().stream()
			.filter(map -> "CS-104".equals(map.getKey()))
			.map(map -> map.getValue()).collect(Collectors.joining());
	System.out.println("Roll: CS-104 , Name :" + studentName);

	/**
	 * Filter more values.Like Filter all Students from Electronics
	 * department (EE) and and whose name starts with B and Collect to a
	 * comma separated String
	 */
	studentName = studentByRoll.entrySet().stream().filter(x -> {
		if (x.getKey().startsWith("EE") && x.getValue().startsWith("B")) {
			return true;
		}
		return false;
	}).map(map -> map.getValue()).collect(Collectors.joining(","));
	System.out.println(studentName);
  }

  public static Map<String, String> getStudentList() {
	Map<String, String> studentByRoll = new HashMap<>();
	studentByRoll.put("CS-101", "Ailsa");
	studentByRoll.put("CS-104", "Amelia");
	studentByRoll.put("CS-105", "Annabel");
	studentByRoll.put("ME-102", "Alice");
	studentByRoll.put("ME-103", "Anwen");
	studentByRoll.put("ME-109", "Arabella");
	studentByRoll.put("ME-104", "Aariyeh");
	studentByRoll.put("EE-103", "Bretton");
	studentByRoll.put("EE-109", "Bleiz");
	studentByRoll.put("EE-107", "Cameleac");
	return studentByRoll;
  }

  public static void prettyPrint(String msg, Map<String, String> inMap) {
	System.out.println("--------------------------------------------");
	System.out.println("## " + msg + ":");
	System.out.println("--------------------------------------------");
	inMap.forEach((k, v) -> System.out.println("| Key :" + k + " | " + "Value :" + v));
	System.out.println();
  }
}

The Output of the program is:

--------------------------------------------
## Filter a Map by key:
--------------------------------------------
| Key :CS-105 | Value :Annabel
| Key :CS-104 | Value :Amelia
| Key :CS-101 | Value :Ailsa

--------------------------------------------
## Filter a Map by more than one key:
--------------------------------------------
| Key :CS-105 | Value :Annabel
| Key :ME-109 | Value :Arabella
| Key :CS-104 | Value :Amelia
| Key :ME-104 | Value :Aariyeh
| Key :ME-102 | Value :Alice
| Key :ME-103 | Value :Anwen
| Key :CS-101 | Value :Ailsa

--------------------------------------------
## Filter a Map by key and value:
--------------------------------------------
| Key :EE-109 | Value :Bleiz
| Key :EE-103 | Value :Bretton

Roll: CS-104 , Name :Amelia
Bleiz,Bretton

 

COLLECTIONS MAP JAVA-8