I've written the following snippet to count the number of occurrences of each element. Is it possible to achieve this in a much shorter way?
int[] arr = {1, 6, 2, 8, 5, 4, 7, 7, 5, 7};
Arrays.stream(arr)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll)
.stream()
.collect(Collectors.groupingBy(s -> s))
.forEach((k, v) -> System.out.println(k+" "+v.size()));
Also I would like to display only the elements which occur more than 1 time. So I tried modifying as below which resulted in an error.
.forEach((k, v) -> if(v.size() > 1) System.out.println(k+" "+v.size()));
What is the correct way to do this?
For the latter question, you have to change
to
For the first part, it's not clear why you need the first
collect
followed by a secondStream
pipeline. If the purpose was to convert anIntStream
to aStream<Integer>
, useboxed()
:As Dici suggested, you can also chain Collectors to group each number with its number of occurrences :
If you are open to using a third-party library, Eclipse Collections has a
Bag
type which can be used as follows:If you have to keep int[] arr variable as an int array, then you can use an
IntBag
. Update: 9/9/16: I have addedselectByOccurrences
to primitiveBags
and it is available in the EC 8.0 release. The following code should work now without having to box the ints usingcollect(i -> i)
:Note: I am a committer for Eclipse Collections.
Also might be done using frequency :
I want to share my solution as well!!!