Filtering
filter() with Predicates, findFirst vs findAny, anyMatch/allMatch/noneMatch and short-circuiting — with Spring Boot examples.
#Introduction
Filtering is one of the most frequently used Stream operations in real-world Java projects and interviews. By the end of this chapter you should be able to answer:
- What is
filter()? - When should I use
findFirst()vsfindAny()? - What are
anyMatch(),allMatch()andnoneMatch()? - How do these work internally?
- Where are they used in Spring Boot projects?
#The filter() Operation
filter() selects elements that satisfy a condition.
stream.filter(predicate)A Predicate<T> is a functional interface:
boolean test(T t);Even Numbers
List<Integer> numbers = Arrays.asList(10, 15, 20, 25, 30);
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);10
20
30Odd Numbers
numbers.stream()
.filter(n -> n % 2 != 0)
.forEach(System.out::println);15
25Names Starting with A
List<String> names = Arrays.asList("Alice", "Bob", "Alex", "David");
names.stream()
.filter(name -> name.startsWith("A"))
.forEach(System.out::println);Alice
AlexAge Greater Than 25
class Employee {
String name;
int age;
Employee(String name, int age) {
this.name = name;
this.age = age;
}
}
List<Employee> employees = Arrays.asList(
new Employee("John", 22),
new Employee("David", 28),
new Employee("Alex", 35)
);
employees.stream()
.filter(e -> e.age > 25)
.forEach(e -> System.out.println(e.name));David
Alex#Multiple Filters
employees.stream()
.filter(e -> e.age > 25)
.filter(e -> e.name.startsWith("A"))
.forEach(e -> System.out.println(e.name));Alex#findFirst()
Returns the first element matching the condition. Return type: Optional<T>.
Optional<Integer> number = numbers.stream()
.filter(n -> n > 10)
.findFirst();
System.out.println(number.get());15Why Optional?
numbers.stream()
.filter(n -> n > 100)
.findFirst();No result exists. Instead of returning null, Java returns Optional.empty(). Safe usage:
numbers.stream()
.filter(n -> n > 100)
.findFirst()
.ifPresent(System.out::println);#findAny()
Returns any matching element.
numbers.stream()
.filter(n -> n > 10)
.findAny();Sequential streams usually return the first match. Parallel streams may return any matching element.
findFirst() vs findAny()
| findFirst() | findAny() |
|---|---|
| Preserves encounter order | May return any matching element |
| Good for ordered streams | Good for parallel streams |
| Usually slightly slower in parallel | Can be faster in parallel |
#Match Operations
anyMatch()
Checks if at least one element matches. Returns boolean.
boolean result = numbers.stream()
.anyMatch(n -> n > 20);
System.out.println(result);trueallMatch()
Checks whether every element satisfies the condition.
numbers.stream().allMatch(n -> n > 0); // true
numbers.stream().allMatch(n -> n % 2 == 0); // falsenoneMatch()
Returns true only if no elements satisfy the condition.
numbers.stream().noneMatch(n -> n < 0); // true
numbers.stream().noneMatch(n -> n > 20); // falseDifference Between Match Operations
List<Integer> list = Arrays.asList(2, 4, 6, 7);| Operation | Code | Result | Why |
|---|---|---|---|
anyMatch() | list.stream().anyMatch(n -> n % 2 != 0) | true | One odd number exists |
allMatch() | list.stream().allMatch(n -> n % 2 == 0) | false | Not every number is even |
noneMatch() | list.stream().noneMatch(n -> n < 0) | true | There are no negative numbers |
#Short-Circuiting
These operations stop as soon as the result is known: findFirst(), findAny(), anyMatch(), allMatch(), noneMatch().
List<Integer> list = Arrays.asList(2, 4, 6, 8, 9, 10);
boolean result = list.stream()
.peek(System.out::println)
.anyMatch(n -> n % 2 != 0);
System.out.println(result);2
4
6
8
9
trueNotice 10 is never processed because the answer is already known after finding 9.
#Real Spring Boot Examples
// Validate user exists
boolean exists = users.stream()
.anyMatch(u -> u.getEmail().equals(email));
// Get first active user
User user = users.stream()
.filter(User::isActive)
.findFirst()
.orElseThrow();
// Check all orders are paid
boolean paid = orders.stream()
.allMatch(Order::isPaid);
// Ensure no expired tokens
boolean valid = tokens.stream()
.noneMatch(Token::isExpired);#Interview Questions
Q1Is filter() an intermediate or terminal operation?
Intermediate.
Q2What is the return type of findFirst()?
Optional<T>.
Q3Why does findFirst() return Optional?
Because there may not be a matching element, and Optional avoids returning null and helps prevent NullPointerException.
Q4Which operations are short-circuiting?
findFirst(), findAny(), anyMatch(), allMatch() and noneMatch() (and limit() among intermediate operations).
Q5Difference between filter() and anyMatch()?
| filter() | anyMatch() |
|---|---|
Returns a Stream<T> | Returns boolean |
| Continues processing until a terminal operation | Stops as soon as one match is found |
| Used to filter a stream | Used to answer a yes/no question |
#Practice Problems
List<Integer> numbers = Arrays.asList(12, 5, 8, 19, 22, 31, 44, 50);- Print all even numbers.
- Print all odd numbers.
- Print numbers greater than 20.
- Print numbers divisible by 4.
- Find the first number greater than 20.
- Find any even number.
- Check if any number is greater than 100.
- Check if all numbers are positive.
- Check if none of the numbers are negative.
- Count how many even numbers are present.
Coding Challenge (Interview Level)
class Employee {
int id;
String name;
String department;
int age;
double salary;
}- Find the first employee whose salary is greater than 100000.
- Check whether any employee belongs to the "HR" department.
- Check whether all employees are older than 18.
- Check whether none of the employees have a negative salary.
- Print employees whose names start with "A" and whose salary is greater than 50000.
#Chapter Summary
filter()andPredicate- Chaining multiple filters
findFirst()vsfindAny()and why they returnOptionalanyMatch(),allMatch(),noneMatch()- Short-circuiting
- Spring Boot usage