Skip to content
Advertisement

Java 11: convert List to TreeMap<String, List> using Collectors

I have a list like that

List<String> customList = Arrays.asList(
   "5000  Buruli ulcer is an infectious disease",
   "6000  characterized by the development",
   "7000  of painless open wounds.",
   "8000  The disease largely occurs in",
   "10000  sub-Saharan Africa and Australia."
);

I want to convert that List into a TreeMap<String, List<String>> like that:

"5000", ["Buruli", "ulcer", "is", "an", "infectious", "disease"]
"6000", ["characterized", "by", "the", "development"]
// etc

My code so far:

TreeMap<String, List<String[]>> collect = customList.stream()
      .map(s -> s.split("  ", 2))
      .collect(Collectors
         .groupingBy(a -> a[0], TreeMap::new, Collectors.mapping(a -> a[1].split(" "), Collectors.toList())));

I have two problems.

  1. First is that TreeMap::new is probably not working because the order is not the same as the original’s List.
  2. Second is that I don’t seem to find a way to make that List<String[]> into a List<String>.

Any ideas?

Answer

You want to use a LinkedHashMap to preserve original order. So your code should look like this:

Map<String, List<String>> collect = customList.stream()
    .map(s -> s.split(" +"))
    .collect(Collectors.toMap(a -> a[0], a -> Arrays.asList(a)
        .subList(1, a.length), (a, b) -> a, LinkedHashMap::new));

If your keys are not unique, you can use the grouping collector with something like this (Collectors.flatMapping requires Java 9+):

collect = customList.stream()
    .map(s -> Arrays.asList(s.split(" +")))
    .collect(Collectors.groupingBy(l -> l.get(0), 
        LinkedHashMap::new, 
        Collectors.flatMapping(l -> l.stream().skip(1), Collectors.toList())));
Advertisement