javajava-stream

Collectors#toMap: No NPEs on null values


What if I don't want Collectors#toMap to throw on null values? Java 8

public class CollectorsTest {

    @Test
    public void collectorsTest() {
        List<Map.Entry<String, Object>> params = Arrays.asList(
                new AbstractMap.SimpleEntry<>("key1", 1),
                new AbstractMap.SimpleEntry<>("key2", null)
        );
        Map<String, Object> paramMap = toParamMap(params); // throws NPE
    }

    private static Map<String, Object> toParamMap(List<Map.Entry<String, Object>> params) {
        Map<String, Object> paramMap = params.stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        return paramMap;
    }
}

Solution

  • The old HashMap.put()

    The modern methods of the standard library, including the methods in the stream package, don’t like nulls as keys or values in maps. Generally for good reasons: nulls are problematic. You may consider a different design where keys with null values are omitted from your map. paramMap.get(yourKey) will still return the null that you say you want.

    There could still be situations where you got legitimate reasons for wanting one or more null values in the map. To obtain that you may use the classic methods from the introduction of the Java collections framework in Java 1.2. It gets just a little wordier:

    private static Map<String, Object> toParamMap(List<Map.Entry<String, Object>> params) {
        Map<String, Object> paramMap = new HashMap<>();
        params.forEach(param -> paramMap.put(param.getKey(), param.getValue()));
        return paramMap;
    }
    

    Trying it out with your example:

        List<Map.Entry<String, Object>> params = Arrays.asList(
                new AbstractMap.SimpleEntry<>("key1", 1),
                new AbstractMap.SimpleEntry<>("key2", null)
        );
        Map<String, Object> paramMap = toParamMap(params);
        System.out.println(paramMap);
    

    Output is a map with a null value in it:

    {key1=1, key2=null}