Home > Blockchain >  Converting list of Map<String, Object> to Map<String,String>
Converting list of Map<String, Object> to Map<String,String>

Time:05-02

I have a list of map.

Map<String, Object> steps1 = new HashMap<>();
steps1.put("key11", "value11");
steps1.put("key12", "value12");
steps1.put("key21","hye");

Map<String, Object> steps2 = new HashMap<>();
steps2.put("key21", "value21");
steps2.put("key22", "value22");
steps2.put("key11","hello");

List<Map<String, Object>> steps = new ArrayList<>();
steps.add(steps1);
steps.add(steps2);

And a list of keys.

List<String> oldKeys = Arrays.asList("key21","key11");

I want to convert the list of map to Map<String,String>, where the values would be comma separated values.

The final result would be :

[key11="value11,hello", key21="hye,value21"]

I can do it by looping and a bit verbose code but want to do it using Java 8 style.

CodePudding user response:

You may try to stream both entry sets, then flatten them to one stream and group by key mapping values to proper string (meanwhile you can filter by your keys)

Stream.of(steps1.entrySet(), steps2.entrySet())
            .flatMap(Set::stream)
            .filter(e -> oldKeys.contains(e.getKey()))
            .collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(v -> String.valueOf(v.getValue()), Collectors.joining(","))));

However I'm always a big fan of writing readable code not fancy one. The example above is quite clear but if it would be too hard to understand you should definitely forgot about "Java 8 style" and write simple loop

CodePudding user response:

Same approach as m.antkowitz but just treating the input as a list of maps as mentioned in the question:

var result = steps.stream()
            .flatMap(map -> map.entrySet()
                    .stream()
                    .filter(entry -> oldKeys.contains(entry.getKey())))
            .collect(toList()).stream()
            .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(e -> e.getValue().toString(),
                            Collectors.joining(","))));

As mentioned, it is a case where streams may not be ideal. Static imports would tidy this up a bit, but even so, it is not a piece of code that I would want to return to and try to understand later on.

Not being facetious, but another option is to use Kotlin, which has a richer set of collection functions particularly around grouping and aggregating. I haven't repeated the exercise in Kotlin but my gut feeling is that something far more readable would be possible.

  • Related