Search code examples
javajava-8java-stream

Java Stream Maintain Map order generated by Collectors.groupingBy()


I have a List of data of type String, trying to get the count of each string as Map<String, Long>

List<String> dataList = new ArrayList();
dataList.addAll(Arrays.asList(new String[] {"a", "z", "c", "b", "a"}));
System.out.println(dataList.stream().collect(Collectors.groupingBy(w -> w, Collectors.counting())));

Output is {a=2, b=2, c=1, z=1}. I wanted the output to maintain the order as provided in list. Like, {a=2, z=1, c=1, b=2}.

LinkedHashMap will maintain the order, but not sure how to user Collectors.groupingBy() to cast output to LinkedHashMap.

Trying to solve the problem using Java8-stream


Solution

  • For this case you should use groupingBy(Function<? super T,? extends K> classifier, Supplier<M> mapFactory,Collector<? super T,A,D> downstream) function:

    Code example:

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.function.Supplier;
    import java.util.stream.Collectors;
    
    import static java.util.stream.Collectors.groupingBy;
    
    public class Main {
    
        public static void main(String[] args){
            List<String> dataList = new ArrayList();
            dataList.addAll(Arrays.asList("a", "z", "c", "b", "a"));
            System.out.println(dataList.stream().collect(groupingBy(w -> w, (Supplier<LinkedHashMap<String, Long>>) LinkedHashMap::new, Collectors.counting())));
        }
    }
    

    Output:

    {a=2, z=1, c=1, b=1}
    

    References:Oracle Documentation