After flattening a Java 8 multilevel map my expected result is empty

SAGAR KALBURGI :

I have the below multilevel map:

Map<String, List<Map<String, Map<String, Map<String, Map<String, String>>>>>> input =
                ImmutableMap.of("A",
                        ImmutableList.of(ImmutableMap.of("2",
                                ImmutableMap.of("3",
                                        ImmutableMap.of("4",
                                                ImmutableMap.of("5", "a"))))));

In short it'll be like

 {
 "A":[{"2":{"3":{"4":{"5":"a"}}}}],
 "B":[{"2":{"3":{"4":{"5":"b"}}}}]
 }

My requirement is to construct a map of the form

{
 "A":"a", 
 "B":"b"
}

I tried the below code but for some reason myMap is always empty even though I'm populating it. What am I missing?

Map<String, String> myMap = new HashMap<>();
input.entrySet()
                .stream()
                .map(l -> l.getValue().stream().map(m -> m.get(m.keySet().toArray()[0]))
                                .map(n -> n.get(n.keySet().toArray()[0]))
                                .map(o -> o.get(o.keySet().toArray()[0]))
                                .map(p -> myMap.put(l.getKey(), p.get(p.keySet().toArray()[0])))).collect(Collectors.toList());
System.out.println(myMap);
ernest_k :

Here's what I get when I add two peek calls to your pipeline:

input.entrySet().stream()
  .peek(System.out::println)     //<- this
  .map(l -> ...)
  .peek(System.out::println)     //<- and this
  .collect(Collectors.toList());

output:

A=[{2={3={4={5=a}}}}]
java.util.stream.ReferencePipeline$3@d041cf

If you notice the problem, you're collecting streams, and these streams don't get executed through a call to a terminal operation... When I try adding something like .count() to the inner stream, your expected output is produced:

...
.map(l -> l.getValue().stream().map(m -> m.get(m.keySet().toArray()[0]))
        .map(n -> n.get(n.keySet().toArray()[0]))
        .map(o -> o.get(o.keySet().toArray()[0]))
        .map(p -> myMap.put(l.getKey(), p.get(p.keySet().toArray()[0])))
        .count()) //just an example
...

Now, I suppose you know that a terminal operation needs to be called for the intermediate ones to run.

In a rather desperate attempt to simplify this code, as the stream seems to make it simply hard to read, I thought you might be interested in this, which assumes that no collection is empty in the tree but at least addrsses the record as one object, and not a collection of records (but I'm sure no code will look clean for that deep map of of maps).

String key = input.keySet().iterator().next();
String value = input.entrySet().iterator().next()
                .getValue().get(0)
                .values().iterator().next()
                .values().iterator().next()
                .values().iterator().next()
                .values().iterator().next();
myMap.put(key, value);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=216817&siteId=1