ZetCode

Java Stream Matching

last modified May 25, 2025

This article demonstrates how to use Java Stream's matching operations: anyMatch, allMatch, and noneMatch for condition checking in streams.

Stream matching operations are terminal operations that check if elements in a stream satisfy certain conditions. They return a boolean value and are short-circuiting (may terminate early without processing all elements).

Basic matching operations

The three matching methods have similar signatures:

boolean anyMatch(Predicate<? super T> predicate)
boolean allMatch(Predicate<? super T> predicate)
boolean noneMatch(Predicate<? super T> predicate)

anyMatch returns true if any element matches the predicate. allMatch returns true if all elements match. noneMatch returns true if no elements match.

anyMatch - Checking for existence

The next exampe uses anyMatch to check if any element satisfies a condition.

Main.java
void main() {

    List<Integer> numbers = List.of(2, 4, 6, 8, 10);
    
    boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0);
    System.out.println("Contains even numbers? " + hasEven);
    
    boolean hasOdd = numbers.stream().anyMatch(n -> n % 2 != 0);
    System.out.println("Contains odd numbers? " + hasOdd);
}

This example checks if the list contains any even numbers (all in this case) and any odd numbers (none in this case). anyMatch stops processing after finding the first match.

$ java Main.java
Contains even numbers? true
Contains odd numbers? false

allMatch - Universal condition

We can use allMatch to verify if all elements meet a condition.

Main.java
void main() {

    List<String> words = List.of("apple", "banana", "avocado", "apricot");
    
    boolean allStartWithA = words.stream().allMatch(s -> s.startsWith("a"));
    System.out.println("All words start with 'a'? " + allStartWithA);
    
    boolean allLongerThan3 = words.stream().allMatch(s -> s.length() > 3);
    System.out.println("All words longer than 3 chars? " + allLongerThan3);
}

This example checks if all words start with 'a' (false) and if all words are longer than 3 characters (true). allMatch stops processing after finding the first non-matching element.

$ java Main.java
All words start with 'a'? false
All words longer than 3 chars? true

noneMatch - Absence verification

We can use noneMatch to ensure no elements satisfy a condition.

Main.java
void main() {

    List<Integer> temperatures = List.of(22, 24, 19, 21, 25);
    
    boolean noneBelowZero = temperatures.stream().noneMatch(t -> t < 0);
    System.out.println("No temperatures below zero? " + noneBelowZero);
    
    boolean noneAbove30 = temperatures.stream().noneMatch(t -> t > 30);
    System.out.println("No temperatures above 30? " + noneAbove30);
}

This example verifies that no temperatures are below zero (true) and none are above 30 (true). noneMatch stops processing after finding the first matching element.

$ java Main.java
No temperatures below zero? true
No temperatures above 30? true

Empty stream behavior

The next example shows how matching operations behave with empty streams.

Main.java
void main() {

    List<String> emptyList = List.of();
    
    boolean any = emptyList.stream().anyMatch(s -> true);
    boolean all = emptyList.stream().allMatch(s -> false);
    boolean none = emptyList.stream().noneMatch(s -> true);
    
    System.out.println("anyMatch: " + any);
    System.out.println("allMatch: " + all);
    System.out.println("noneMatch: " + none);
}

This example demonstrates the behavior with empty streams: anyMatch returns false, allMatch returns true (vacuously true), and noneMatch returns true.

$ java Main.java
anyMatch: false
allMatch: true
noneMatch: true

Complex object matching

The next example demonstrates matching operations on a list of custom objects, using a record class to represent products.

Main.java
record Product(String name, double price, boolean inStock) {}

void main() {

    List<Product> inventory = List.of(
        new Product("Laptop", 999.99, true),
        new Product("Phone", 699.99, false),
        new Product("Tablet", 349.99, true)
    );
    
    boolean anyExpensive = inventory.stream()
        .anyMatch(p -> p.price() > 800);
    System.out.println("Any expensive products? " + anyExpensive);
    
    boolean allInStock = inventory.stream()
        .allMatch(Product::inStock);
    System.out.println("All products in stock? " + allInStock);
    
    boolean noneFree = inventory.stream()
        .noneMatch(p -> p.price() == 0);
    System.out.println("No free products? " + noneFree);
}

This example checks various conditions on a list of Product objects, demonstrating how matching operations work with complex predicates on object properties.

$ java Main.java
Any expensive products? true
All products in stock? false
No free products? true

Short-circuiting behavior

The next example demonstrates the short-circuiting nature of matching operations.

Main.java
void main() {

    boolean result = IntStream.range(1, 1000)
        .peek(n -> System.out.println("Processing: " + n))
        .anyMatch(n -> n % 42 == 0);
    
    System.out.println("Found multiple of 42? " + result);
}

This example shows how anyMatch stops processing after finding the first multiple of 42. The peek operation reveals which numbers are actually processed.

$ java Main.java
Processing: 1
Processing: 2
...
Processing: 42
Found multiple of 42? true

Combining with other operations

The next example combines matching operations with other stream operations to demonstrate their flexibility.

Main.java
void main() {

    List<String> mixed = List.of("1", "2", "three", "4", "five");
    
    boolean allNumeric = mixed.stream()
        .map(s -> {
            System.out.println("Mapping: " + s);
            return s;
        })
        .filter(s -> s.length() == 1)
        .allMatch(s -> Character.isDigit(s.charAt(0)));
    
    System.out.println("All single chars are digits? " + allNumeric);
}

This example checks if all single-character strings are digits, demonstrating how matching operations work with transformed streams. Note the processing order.

$ java Main.java
Mapping: 1
Mapping: 2
Mapping: three
Mapping: 4
Mapping: five
All single chars are digits? true

Source

Java Stream matching documentation

In this article we have explored Java Stream's matching operations. anyMatch, allMatch, and noneMatch provide powerful ways to check conditions on stream elements with efficient short-circuiting behavior. These operations are essential for writing concise and efficient stream-based condition checks.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Java tutorials.