Reputation: 2161
I have a utility method defined as below.
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;
}
The String.valueOf(e.getValue())
returns a "null" value from the call. I would like to get the null
value for the string.
When I tried the below code, I get an NPE on first .collect
call.
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;
}
Upvotes: 0
Views: 1046
Reputation: 298143
The toMap
collector doesn’t support null
values. But it doesn’t always have to be the 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()));
}
The utility method returns a map with the same keys and transformed values and is flexible enough to allow a recursive application to do the inner map transformation.
Alternatively, we may adapt the solution of this answer to
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)));
}
Unlike the original toMap
collector, this won’t throw on duplicate keys, but for this specific case where the input is already a Map
, there shouldn’t be duplicate keys anyway.
Upvotes: 1