Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 streams: count values

I am trying to get the number of ocurrences of an object in the set of values in a list using Java 8 streams, but I can't get the hang of it yet.

This is what I am trying to do:

int threshold = 5;
for (Player player : match) { // match is a Set<Player>
    int count = 0;
    for (Set<Player> existingMatch : matches)
        if (existingMatch.contains(player))
            count++;
    if (count >= threshold )
        throw new IllegalArgumentException("...");
}

I know I can group with collect and groupingBy, and use a filter saying that the operation to apply is contains with the new method reference operator. But I am still too green with these new Java 8 features and cannot put it all together.

So how could I extract the number of ocurrences of player in all set of values in a list, using Stream?

like image 539
dabadaba Avatar asked May 02 '16 19:05

dabadaba


People also ask

How do you count streams in Java?

In Java 8, there is predefined counting() method returned by Collectors class counting() method to count the number of elements in a Stream. Syntax : public static Collector counting() Where, output is a Collector, acting on a Stream of elements of type T, with its finisher returning the 'collected' value of type Long.

How do I count the number of elements in Java 8?

Java 8 | Collectors counting() with ExamplesCollectors counting() method is used to count the number of elements passed in the stream as the parameter. It returns a Collector accepting elements of type T that counts the number of input elements. If no elements are present, the result is 0.

Are Java 8 streams lazy?

Streams are lazy because intermediate operations are not evaluated until terminal operation is invoked. Each intermediate operation creates a new stream, stores the provided operation/function and return the new stream. The pipeline accumulates these newly created streams.


1 Answers

Lambda expressions can help separate the different bits of logic and then compose them together.

As I understand from your code, you are testing players for whether they are contained in at least threshold elements of matches. We can write the test logic as follows:

Predicate<Player> illegalTest = player -> matches.stream()
        .filter(m -> m.contains(player))
        .count() >= threshold;

Then we want to apply this test to see if any of the players matches:

boolean hasIllegal = match.stream().anyMatch(illegalTest);

And finally:

if (hasIllegal) {
    throw new IllegalArgumentException("...");
}
like image 104
Misha Avatar answered Oct 01 '22 02:10

Misha