Skip to main content
  1. blog/

Java Streams: Use anyMatch() over count() > 0 for checking at least one occurrence

·3 mins

Overview #

Streams were introduced in Java 8. When working with streams, there are times when we just want to determine if there is at least one occurrence that matches our predicate or criteria.

In this article, I’ll discuss why using the anyMatch(predicate) method in the Java Stream API is both safer and more performant than using filter(predicate).count > 0 in these situations.


Short Circuiting #

The fundamental difference between anyMatch() and count() is that anyMatch() is short-circuiting which means it will stop at the first match whereas count() will count all matches before returning.

Depending upon the stream size, this difference could have huge performance implications.

A Stream of 100,000 objects #

Imagine working with a list of 100,000 Employee objects where we want to determine if any employees are inactive:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.codebyamir.streams;

import java.util.ArrayList;
import java.util.List;

class Employee {
    private boolean isActive;

    public Employee(boolean isActive) {
        this.isActive = isActive;
    }

    public boolean isActive() {
        return isActive;
    }

    public void setActive(boolean active) {
        isActive = active;
    }
}

public class Main {

    public static void main(String[] args) {

        List<Employee> employees = new ArrayList<>();

        // Create 100,000 objects
        for (int i = 0; i < 100_000; i++) {
            boolean active = false;

            if (i % 4 == 0) {
                active = true;
            }

            employees.add(new Employee(active));
        }

        boolean result = false;

        System.out.println("count() > 0");
        System.out.println("---------------------");
        System.out.println("Start time:\t" + System.currentTimeMillis());
        result = employees.stream().filter(e -> !e.isActive()).count() > 0;
        System.out.println("End time:\t" + System.currentTimeMillis());

        System.out.println();

        System.out.println("anyMatch()");
        System.out.println("---------------------");
        System.out.println("Start time:\t" + System.currentTimeMillis());
        result = employees.stream().anyMatch(e -> !e.isActive());
        System.out.println("End time:\t" + System.currentTimeMillis());
    }
}

Output #

count() > 0
---------------------
Start time:	1583177821492
End time:	1583177821512

anyMatch()
---------------------
Start time:	1583177821512
End time:	1583177821513

As we can see from the sample output, anyMatch is substantially faster (1ms) than count (20ms).

An Infinite Stream #

If we end up creating an infinite stream of elements such as the code below, then the count() method will never terminate where as the anyMatch() approach will terminate upon finding the first match.

count #

IntStream infiniteStream = IntStream.iterate(0, i -> i + 2);

// Never terminates
boolean test = stream.filter(i -> i <= 50).count() > 0;

anyMatch #

IntStream infiniteStream = IntStream.iterate(0, i -> i + 2);

// Terminates at first match of i <= 50
boolean test = stream.anyMatch(i -> i <= 50);