0

I need to count a number of occurrences for each string in

ArrayList<ArrayList<String>>

I know how to do it the old java 7 and below way, but want to do it using streams and collectors

Ideally, I would save the result in the HashMap<String, Integer>, where integer is a number of occurrences and String is the corresponding string.

This can be vice versa - not a big deal.

I found solution how to do it for ArrayList here

Map<String, Long> counts =
    list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

but my case is more complex since it's an ArrayList of ArrayLists.

The structure is following String itemId = list.get(i).getProducts().get(j).getItemId();

Community
  • 1
  • 1
Andrei
  • 801
  • 2
  • 10
  • 27
  • 4
    What do you mean with “count number of duplicates”? Do you rather mean “number of occurrences”? – Holger Feb 10 '17 at 19:57

1 Answers1

7

If you want to count the number of occurrences, regardless of in which sub-list the strings appear, you can use

Map<String, Long> counts = list.stream().flatMap(List::stream)
   .collect(Collectors.groupingBy(e -> e, Collectors.counting()));

if having Integer as value type is important to you, you can use

Map<String, Integer> counts = list.stream().flatMap(List::stream)
    .collect(Collectors.groupingBy(e -> e, Collectors.summingInt(x -> 1)));

instead.

Additionally, a solution based on conventional loops can also benefit from Java 8 features:

Map<String, Integer> counts = new HashMap<>();
for(List<String> l: list)
    for(String s: l)
        counts.merge(s, 1, Integer::sum);
Holger
  • 285,553
  • 42
  • 434
  • 765
  • I am getting the following error (for the first option that you mentioned). Multiple markers at this line - Stream cannot be resolved - Type mismatch: cannot convert from Stream to – Andrei Feb 15 '17 at 17:02
  • Well, if it says, “Stream cannot be resolved”, you have serious problems in your project setup, as the code above doesn’t contain any reference to `Stream`. But still, check whether you have correctly imported every type you are using. Or do you mean “stream” (lowercase)? The code above assumes that you have an `ArrayList>` as you stated in your question, not anything having a `getProducts()` method as appended to it five days later. – Holger Feb 15 '17 at 17:15
  • You can fix it by changing `.flatMap(List::stream)` to `.flatMap(o->o.getProducts().stream())`, but in the future, provide a correct problem description right when you post your question initially. – Holger Feb 15 '17 at 17:21