Java8 Streams - 如何将内部映射的键值从 "null" 字符串修改为空对象
Java8 Streams - How to modify value of keys of inner map to null object from "null" string
我有一个实用方法定义如下。
public static Map<String, Map<String, String>> convertRawMapToStringValues(Map<String, Map<String, Object>> cassandraRowsRawMap) {
Map<String, Map<String, String>> cassandraStrValuesMap = cassandraRowsRawMap.entrySet()
.stream()
.collect(Collectors.toMap(s -> s.getKey(),
s -> s.getValue().entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey(),
e -> String.valueOf(e.getValue())))));
return cassandraStrValuesMap;
}
String.valueOf(e.getValue())
returns 一个 "null" 值来自调用。我想获取字符串的 null
值。
当我尝试下面的代码时,我在第一次 .collect
调用时得到了一个 NPE。
Map<String, Map<String, String>> cassandraStrValuesMap = cassandraRowsRawMap.entrySet()
.stream()
.collect(Collectors.toMap(s -> s.getKey(),
s -> s.getValue().entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey(),
e -> e.getValue() == null ? null : String.valueOf(e.getValue())))));
return cassandraStrValuesMap;
}
toMap
收集器不支持 null
值。但它并不总是必须是 Stream API:
public static <K,T,R> Map<K,R> changeValues(
Map<? extends K, T> in, Function<? super T, ? extends R> f) {
Map<K,R> result = new HashMap<>(in.size());
in.forEach((k,t) -> result.put(k, f.apply(t)));
return result;
}
public static Map<String, Map<String, String>> convertRawMapToStringValues(
Map<String, Map<String, Object>> in) {
return changeValues(in, inner -> changeValues(inner, v -> v==null? null: v.toString()));
}
实用方法 returns 具有相同键和转换值的映射,并且足够灵活以允许递归应用程序进行内部映射转换。
或者,我们可以将 this answer 的解决方案调整为
public static Map<String, Map<String, String>> convertRawMapToStringValues(
Map<String, Map<String, Object>> in) {
return in.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().entrySet().stream()
.collect(
HashMap::new,
(m,e2) -> m.put(e2.getKey(),
e2.getValue() == null? null: e2.getValue().toString()),
Map::putAll)));
}
与最初的 toMap
收集器不同,这不会引发重复键,但对于输入已经是 Map
的特定情况,无论如何都不应该有重复键。
我有一个实用方法定义如下。
public static Map<String, Map<String, String>> convertRawMapToStringValues(Map<String, Map<String, Object>> cassandraRowsRawMap) {
Map<String, Map<String, String>> cassandraStrValuesMap = cassandraRowsRawMap.entrySet()
.stream()
.collect(Collectors.toMap(s -> s.getKey(),
s -> s.getValue().entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey(),
e -> String.valueOf(e.getValue())))));
return cassandraStrValuesMap;
}
String.valueOf(e.getValue())
returns 一个 "null" 值来自调用。我想获取字符串的 null
值。
当我尝试下面的代码时,我在第一次 .collect
调用时得到了一个 NPE。
Map<String, Map<String, String>> cassandraStrValuesMap = cassandraRowsRawMap.entrySet()
.stream()
.collect(Collectors.toMap(s -> s.getKey(),
s -> s.getValue().entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey(),
e -> e.getValue() == null ? null : String.valueOf(e.getValue())))));
return cassandraStrValuesMap;
}
toMap
收集器不支持 null
值。但它并不总是必须是 Stream API:
public static <K,T,R> Map<K,R> changeValues(
Map<? extends K, T> in, Function<? super T, ? extends R> f) {
Map<K,R> result = new HashMap<>(in.size());
in.forEach((k,t) -> result.put(k, f.apply(t)));
return result;
}
public static Map<String, Map<String, String>> convertRawMapToStringValues(
Map<String, Map<String, Object>> in) {
return changeValues(in, inner -> changeValues(inner, v -> v==null? null: v.toString()));
}
实用方法 returns 具有相同键和转换值的映射,并且足够灵活以允许递归应用程序进行内部映射转换。
或者,我们可以将 this answer 的解决方案调整为
public static Map<String, Map<String, String>> convertRawMapToStringValues(
Map<String, Map<String, Object>> in) {
return in.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().entrySet().stream()
.collect(
HashMap::new,
(m,e2) -> m.put(e2.getKey(),
e2.getValue() == null? null: e2.getValue().toString()),
Map::putAll)));
}
与最初的 toMap
收集器不同,这不会引发重复键,但对于输入已经是 Map
的特定情况,无论如何都不应该有重复键。