I have a nested class structure that I use to deserialize my data:
Class A has a single property that is an object of Class B (say b)
Class B has a single property that is an object of Class C (say c)
Class C has a single property that is an object of Class D (say d)
Class D has a single property that is a a string (say e)
I have data that looks like
Map<String, List<Map<String, Map<String, Map<String, Map<String, String>>>>>> input =
ImmutableMap.of("Key",
ImmutableList.of(ImmutableMap.of("a",
ImmutableMap.of("b",
ImmutableMap.of("c",
ImmutableMap.of("d", "e"))))));
I want to parse this multilevel map and put the result into a map
Map<String, String> result = new HashMap<>();
At the end, I expect result
map to contain this at the end: ["key", "e"]
I have this code that works if the map contain all the intermediate keys a, b, c and d
mapping.entrySet()
.stream()
.map(l -> l.getValue().stream()
.map(Optional::ofNullable)
.map(opta -> opta.map(A::getB))
.map(optb -> optb.map(B::getC))
.map(optc -> optc.map(C::getD))
.map(optd -> optd.map(D::getE))
.map(optv -> optv.orElse("default"))
.map(m -> result.put(l.getKey(), m))
.count())
.count();
but for example say if the input is
Map<String, List<Map<String, Map<String, Map<String, Map<String, String>>>>>> input =
ImmutableMap.of("Key",
ImmutableList.of(ImmutableMap.of("a",
ImmutableMap.of("b",null))));
then my code fails:
java.lang.NullPointerException: null value in entry: b=null
Why is my Optional.isNullable
not working?
You are using ImmutableMap
, and ImmutableMap
does not like null
key or value: https://guava.dev/releases/23.0/api/docs/com/google/common/collect/ImmutableMap.html#of-K-V-
public static <K,V> ImmutableMap<K,V> of(K k1, V v1)
Returns an immutable map containing a single entry. This map behaves and performs comparably to
Collections.singletonMap(K, V)
but will not accept a null key or value. It is preferable mainly for consistency and maintainability of your code.
The message is produced by this method: https://github.com/google/guava/blob/82b3e9806dc3422e51ecb9400d8f50404b083dde/guava/src/com/google/common/collect/CollectPreconditions.java#L28
static void checkEntryNotNull(Object key, Object value) {
if (key == null) {
throw new NullPointerException("null key in entry: null=" + value);
} else if (value == null) {
throw new NullPointerException("null value in entry: " + key + "=null");
}
}
On the other hand, I think you should use specialized rather than map... I'm pretty sure that such kind of type is giving headache to your team or other reader:
Map<String, List<Map<String, Map<String, Map<String, Map<String, String>>>>>>