2

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

Bala
  • 749
  • 11
  • 27
  • 3
    https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#groupingBy-java.util.function.Function-java.util.function.Supplier-java.util.stream.Collector- – JB Nizet Sep 15 '17 at 18:06

3 Answers3

2

Per JB Nizet dataList.stream().collect(Collectors.groupingBy(w -> w, LinkedHashMap::new, Collectors.counting()))

Bala
  • 749
  • 11
  • 27
2

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

Gabriel F
  • 161
  • 5
  • 1
    The type cast `(Supplier>)` should not be necessary. A simple `dataList.stream().collect(groupingBy(w -> w, LinkedHashMap::new, counting()))` should do… – Holger Sep 18 '17 at 09:14
0

Not as simple as the given solutions, but just for illustration: you can use a TreeMap as well, with a suitable Comparator, like:

List<Character> list = Arrays.asList('q', 'a', 'z', 'c', 'b', 'z', 'a');
Comparator<Character> comp = Comparator.comparing(list::indexOf);
Map<Character, Long> map = list.stream()
    .collect(groupingBy(c -> c, () -> new TreeMap<>(comp), counting()))
;
System.out.println(map);