0

I'm new to Streams and I want something like this: I have an input Map with <String, List<String>>. I want to read this map in a stream and assign it to an output map with <String, String> with the value being the first element of the value list from input map. Example:

**Input:**
{key1, [value1 value2]}
{key2, null}

**Output**
{key1, value1}
{key2, null}

Notice, when the list in the first map is null, then it should be written as null in the second map. If the list is empty, then it should also write null in the second map value

What I have tried:

Map<String, String> output= input.entrySet().stream()
                    .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get(0)));

This gives a java.lang.NullPointerException when the list is empty in the first map.

0

1 Answer 1

1

Unfortunately, Collectors.toMap will also throw if you put a null value in.

To get around this, you can in-line build a Collector for Map. For example, something like:

final Map<String, String> output = input.entrySet().stream()
        .collect(HashMap::new, // Create a Map if none is present
                (map, entry) -> map.put(entry.getKey(), // Keys stay the same
                (entry.getValue() == null || entry.getValue().isEmpty()) // Check for empty
                    ? null : entry.getValue().iterator().next()), // Get first if present
                HashMap::putAll); // Combining function

Note: wrapping this with Collections.unmodifiableMap makes sense to avoid future contamination. Note: Pulling out the 'get first value or null' to a method like the following is probably considerably more readable, and allows the combining bit to just become this.getFirstIfPresent(entry.getValue()) in the above pipeline:

private static <T> @Nullable T getFirstIfPresent(final List<T> input) {
    if (list == null || list.isEmpty()) {
        return null;
    }

    return list.iterator().next();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.