Search code examples
javacollectionsjava-8java-streamcollectors

Collectors.groupingBy for Map<Long, List<String>> with some string manipulation


I have the following List<String>, resultList that I want to convert to a Map<Long, List<String>>

["7802,Campaign submitted - audience list", "7802,Test Static Coupon", "7802,submit order", "7802,order creation failed", "7802,submit order", "8153,existing order test - resubmitting", "8153,existing order test - reorder", "8153,test", "8153,test", "8953,audience newly duplicated list"]

The Map should look like the following:

{
   7802: [Campaign submitted - audience list, Test Static Coupon, submit order, order creation failed, submit order],
   8153: [existing order test - resubmitting, existing order test - reorder, test, test],
   8953: [audience newly duplicated list]
}

I have the following code so far but I can't figure out how to manipulate the strings to save to the list in the Map:

resultList.stream().collect(
      Collectors.groupingBy(s -> Long.parseLong(s.substring(0, s.indexOf(','))), 
      HashMap::new, 
      Collectors.toCollection(ArrayList::new)));

The code above returns the following:

{
   7802: [7802,Campaign submitted - audience list, 7802,Test Static Coupon, 7802,submit order, 7802,order creation failed, 7802,submit order],
   8153: [8153,existing order test - resubmitting, 8153,existing order test - reorder, 8153,test, 8153,test],
   8953: [8953,audience newly duplicated list]
}

How can I manipulate the strings to get the required output?


Solution

  • It would be more convenient to work with if you split up the two parts of the string first, using map. With a Stream<String[]>, you can group by x[0], and map the groups to x[1] using a downstream collector.

    var result = list.stream()
        .map(x -> x.split(",", 2))
        .collect(Collectors.groupingBy(
            x -> Long.parseLong(x[0]),
            Collectors.mapping(x -> x[1], Collectors.toList())
        ));
    

    If you specifically want HashMaps and ArrayLists instead:

    var result = list.stream()
        .map(x -> x.split(",", 2))
        .collect(Collectors.groupingBy(
            x -> Long.parseLong(x[0]),
            HashMap::new,
            Collectors.mapping(x -> x[1], Collectors.toCollection(ArrayList::new))
        ));