Following the same principles found in filtering a map by entries and filtering a map by values, this example will show how to filter a map by Map.key while using java, java 8 and guava. Each of the snippets below will use a predefined map created in the @setup where the entries resemble a month. The Map.key is the integer month of year (1=January) and the value represents the month spelled out. A comparable example demonstrates how to filter a map by keys in groovy.
Setup
Map<Integer, String> MONTHS = new HashMap<Integer, String>();
@Before
public void setUp () {
MONTHS.put(new Integer(1), "January");
MONTHS.put(new Integer(2), "February");
MONTHS.put(new Integer(3), "March");
MONTHS.put(new Integer(4), "April");
MONTHS.put(new Integer(5), "May");
MONTHS.put(new Integer(6), "June");
MONTHS.put(new Integer(7), "July");
MONTHS.put(new Integer(8), "August");
MONTHS.put(new Integer(9), "September");
MONTHS.put(new Integer(10), "October");
MONTHS.put(new Integer(11), "November");
MONTHS.put(new Integer(12), "December");
}
Straight up Java
The core jdk lack the mechanics for filtering a map by Map.key until java 8. As shown in the snippet below, the only effective way is to iterate over the Map.entrySet using a for loop and then applying criteria in an if statement, in this case checking if entry.key is less than four or finding months contained in the first quarter.
@Test
public void filter_map_by_keys_java () {
Map<Integer, String> firstQuarter = new HashMap<Integer, String>();
for (Entry<Integer, String> entry : MONTHS.entrySet()) {
if (entry.getKey().intValue() <= 4) {
firstQuarter.put(entry.getKey(), entry.getValue());
}
}
logger.info(firstQuarter);
assertThat(firstQuarter.keySet(), contains(
1, 2, 3, 4));
}
Output
{1=January, 2=February, 3=March, 4=April}
Java 8
The snippet below will show how to filter a map by keys using java 8. Using the powerful streams api, we will call entrySet.stream and filter months within the first quarter. We created this java.util.function.predicate by using a lambda expression. Then using Collectors.toMap we will map each element in the stream back into a map.
@Test
public void filter_map_by_keys_java8_lambda () {
Map<Integer, String> firstQuarter =
MONTHS.entrySet()
.stream()
.filter(p -> p.getKey().intValue() <= 4)
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
logger.info(firstQuarter);
assertThat(firstQuarter.keySet(), contains(
1, 2, 3, 4));
}
Output
{1=January, 2=February, 3=March, 4=April}
Google Guava
Using guava Maps collection utility we will call Maps.filterKeys which accepts a map and a guava predicate as parameters then returning a map containing the mappings whose keys satisfy the predicate.
@Test
public void filter_map_by_keys_guava () {
Predicate<Integer> byFirstQuarter = new Predicate<Integer>() {
@Override
public boolean apply(Integer input) {
return input.intValue() <= 4;
}
};
Map<Integer, String> firstQuarter = Maps.filterKeys(MONTHS, byFirstQuarter);
logger.info(firstQuarter);
assertThat(firstQuarter.keySet(), contains(
1, 2, 3, 4));
}
Output
{1=January, 2=February, 3=March, 4=April}