1

I have a list of strings that must be split using a delimiter and then get the second value of the split to create a map of string arrays.

Here is an example:

A list of strings like the following:

["item1:parent1", "item2:parent1", "item3:parent2"]

Should be converted to a map that has the following entries:

<key: "parent1", value: ["item1", "item2"]>,
<key: "parent2", value: ["item3"]>

I tried to follow the solution given in this question but with no success

Sample code:

var x = new ArrayList<>(List.of("item1:parent1", "item2:parent1", "item3:parent2"));
var res = x.stream().map(s->s.split(":")).collect(Collectors.groupingBy(???));
user1798707
  • 351
  • 1
  • 3
  • 12

2 Answers2

4

Assuming the splited array has always a length of 2, something like below should work

var list = List.of("item1:parent1", "item2:parent1", "item3:parent2");
var map = list.stream()
            .map(s -> s.split(":"))
            .collect(Collectors.groupingBy(
                    s -> s[1], 
                    Collectors.mapping(s -> s[0],  Collectors.toList())));
    
System.out.println(map);
Eritrean
  • 15,851
  • 3
  • 22
  • 28
1

@Eritrean has shown how to do it with streams. Here's another way:

Map<String, List<String>> result = new LinkedHashMap<>();
x.forEach(it -> {
    String[] split = it.split(":");
    result.computeIfAbsent(split[1], k -> new ArrayList<>()).add(split[0]);
});

This uses Map.computeIfAbsent, which comes in handy for cases like this.

fps
  • 33,623
  • 8
  • 55
  • 110