anyMatch(), allMatch() and noneMatch()

One common task when working with streams in Java is to perform boolean operations on its elements. To accomplish this, Java provides three methods: allMatch()anyMatch(), and noneMatch(). The allMatch(), noneMatch(), and anyMatch() methods are three important stream operations in Java 8 that provide a concise way to check conditions on a stream of elements. These methods are categorized as terminal operations, meaning they consume the entire stream and produce a single result.

These three methods are useful for filtering streams based on specific criteria. They are particularly powerful when combined with other stream operations, such as filter() and map(), to perform more complex transformations and calculations on stream elements.

allMatch()

The allMatch() method evaluates whether all elements in the stream satisfy a specified predicate. It returns true if all elements match the predicate, and false otherwise. The predicate is an inline lambda expression or a method reference that takes an element of the stream as its argument and returns a boolean value. If the stream is empty, allMatch() returns true.

Syntax:

				
					boolean allMatch(Predicate<? super T> predicate)

				
			

Example:

				
					//1. Check if all words have length more than 2
List<String> words = Arrays.asList("apple", "banana", "cherry");
boolean allMatchLength = words.stream().allMatch(word -> word.length() > 2);
System.out.println(allMatchLength); // Output: true

//2. Check with all the names start with 'A'

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
boolean allNamesStartWithA = names.stream().allMatch(name -> name.startsWith("A"));
System.out.println(allNamesStartWithA); // Output: false


				
			

noneMatch()

The noneMatch() method checks if none of the elements in the stream match a specified predicate. It returns true if none of the elements match the predicate, and false otherwise. The predicate is an inline lambda expression or a method reference that takes an element of the stream as its argument and returns a boolean value. If the stream is empty, noneMatch() returns true.

Syntax:

				
					boolean noneMatch(Predicate<? super T> predicate)

				
			

Example:

				
					//1. Check if all the fruit names are uppercase
List<String> fruits = Arrays.asList("apple", "banana", "cherry");

boolean noneMatchUpperCase = fruits.stream().noneMatch(fruit -> fruit.equals(fruit.toUpperCase()));
System.out.println(noneMatchUpperCase); // Output: true

				
			

anyMatch()

The anyMatch() method determines if at least one element in the stream matches a specified predicate. It returns true if at least one element matches the predicate, and false otherwise. The predicate is an inline lambda expression or a method reference that takes an element of the stream as its argument and returns a boolean value. If the stream is empty, anyMatch() returns false.

Syntax:

				
					boolean anyMatch(Predicate<? super T> predicate)

				
			

Example:

				
					//1. Check if some fruits name starts With 'A'
List<String> fruits = Arrays.asList("Apple", "Banana", "Orange");
boolean someFruitStartsWithA = fruits.stream().anyMatch(fruit -> fruit.startsWith("A"));
System.out.println(someFruitStartsWithA); // Output: true

				
			

Practical Use Case

In this example, we’ve created a class BankAccount and added three objects of the BankAccount class (account1, account2, account3) and created a list (bankAccounts) containing all three bank accounts. After performing transactions, we use Java Streams to check below conditions on the bank accounts.

allMatch: Checks if all accounts have a balance greater than $1000.
noneMatch: Checks if none of the accounts have a balance less than $500.
anyMatch: Checks if any account has a balance greater than $1500.

				
					// BankAccount Class

public class BankAccount {
    // Attributes
    private String accountHolder;
    private double balance;

    // Constructor
    public BankAccount(String accountHolder, double initialBalance) {
        this.accountHolder = accountHolder;
        this.balance = initialBalance;
    }

    // Methods
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposit of $" + amount + " successful. New balance: $" + balance);
        } else {
            System.out.println("Invalid deposit amount.");
        }
    }

    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("Withdrawal of $" + amount + " successful. New balance: $" + balance);
        } else {
            System.out.println("Invalid withdrawal amount or insufficient funds.");
        }
    }

    public void checkBalance() {
        System.out.println("Account balance for " + accountHolder + ": $" + balance);
    }
    
    public double getBalance() {
    return balance;
   }
}


// Main Class

import java.util.Arrays;
import java.util.List;

public class BankingSystem {
    public static void main(String[] args) {
        // Creating BankAccount objects
        BankAccount account1 = new BankAccount("John Doe", 1000.0);
        BankAccount account2 = new BankAccount("Jane Doe", 500.0);
        BankAccount account3 = new BankAccount("Bob Smith", 1500.0);

        // Creating a list of bank accounts
        List<BankAccount> bankAccounts = Arrays.asList(account1, account2, account3);

        // Performing transactions
        account1.deposit(500.0);
        account1.withdraw(200.0);

        account2.withdraw(100.0);
        account2.deposit(300.0);

        account3.deposit(1000.0);

        // Checking conditions using Java Streams
        boolean allAccountsHaveMoreThan1000 = bankAccounts.stream().allMatch(account -> account.getBalance() > 1000.0);
        boolean noneAccountHasLessThan500 = bankAccounts.stream().noneMatch(account -> account.getBalance() < 500.0);
        boolean anyAccountHasMoreThan1500 = bankAccounts.stream().anyMatch(account -> account.getBalance() > 1500.0);

        // Displaying results
        System.out.println("All accounts have more than $1000: " + allAccountsHaveMoreThan1000);
        System.out.println("None account has less than $500: " + noneAccountHasLessThan500);
        System.out.println("Any account has more than $1500: " + anyAccountHasMoreThan1500);
    }
}

				
			
				
					// Output
Deposit of $500.0 successful. New balance: $1500.0
Withdrawal of $200.0 successful. New balance: $1300.0
Withdrawal of $100.0 successful. New balance: $400.0
Deposit of $300.0 successful. New balance: $700.0
Deposit of $1000.0 successful. New balance: $2500.0

All accounts have more than $1000: false
None account has less than $500: true
Any account has more than $1500: true
				
			

Conclusion

Java Streams, with their powerful set of operations, elevate the language to new heights. The trio of allMatch, noneMatch, and anyMatch adds valuable tools to your toolkit, enabling you to succinctly express complex conditions on your data. As you continue to explore Java Streams, remember that these methods are your allies in creating clean, efficient, and expressive code.