将map< string,list< string>>输入分配给map< string,list< string>>输出

daolsyd0  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(402)

我对streams很陌生,我想要这样的东西:我有一个带有 <String, List<String>> . 我想在一个流中读取这个Map,并用 <String, String> 值是输入Map中值列表的第一个元素。例子:


**Input:**

{key1, [value1 value2]}
{key2, null}

**Output**

{key1, value1}
{key2, null}

注意,当第一个Map中的列表为null时,第二个Map中的列表应写为null。如果列表为空,那么它还应该在第二个Map值中写入null
我尝试过:

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

这给了一个 java.lang.NullPointerException 当列表在第一个Map中为空时。

xxls0lw8

xxls0lw81#

不幸的是, Collectors.toMap 如果你放一个 null 中的值。
为了解决这个问题,你可以在线构建一个 Collector 为了 Map . 例如,类似于:

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

注意:用 Collections.unmodifiableMap 避免将来的污染是有意义的。注意:将“get first value or null”提取到下面这样的方法可能更可读,并允许组合位变得更简单 this.getFirstIfPresent(entry.getValue()) 在上述管道中:

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

    return list.iterator().next();
}

相关问题