Definition
- Objects::nonNull is a method reference that returns true for non-null values, removing nulls from the stream.
- String::isBlank (Java 11) returns true for empty strings AND whitespace-only strings like " ".
- Predicate.not(String::isBlank) negates the predicate cleanly without a lambda.
- Order matters: nonNull must come BEFORE isBlank. Calling isBlank on null throws
NullPointerException. - For Java 8, use
!s.trim().isEmpty()instead of!s.isBlank()because isBlank was added in Java 11. isBlank()treats tabs, non-breaking spaces, and other Unicode whitespace as blank.
At National Bank of India, a CSV import of beneficiary names contains blank cells (empty strings), missing values (nulls), and cells with only spaces (" "). Before validation, the bank discards all three types. First remove nulls (missing cells), then remove blanks (empty and whitespace-only cells).
Understanding the Concepts
How do you clean an array of strings?
package com.bank.util;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class CleanStringsDemo {
public static void main(String[] args) {
String[] names = {"Rajesh", null, "", "Priya", " ", null, "Amit"};
List<String> clean = Arrays.stream(names)
.filter(Objects::nonNull)
.filter(Predicate.not(String::isBlank))
.toList();
System.out.println("Clean: " + clean);
}
}
Clean: [Rajesh, Priya, Amit]
Why must nonNull come first?
// WRONG: isBlank on null throws NullPointerException
Arrays.stream(names)
.filter(s -> !s.isBlank()) // NPE when s is null!
.toList();
// CORRECT: nonNull first, then isBlank
Arrays.stream(names)
.filter(Objects::nonNull) // removes nulls
.filter(Predicate.not(String::isBlank)) // removes blanks
.toList();
How is isBlank different from isEmpty?
| Method | Empty "" | Whitespace " " | Null |
|--------|---------|-----------------|------|
| isEmpty() | true | false | NPE |
| isBlank() (Java 11) | true | true | NPE |
| trim().isEmpty() | true | true | NPE |
isBlank() is strictly better than isEmpty() for cleaning because it catches whitespace-only strings.
How do you combine filters into one predicate?
// Combined predicate (single filter)
List<String> combined = Arrays.stream(names)
.filter(s -> s != null && !s.isBlank())
.toList();
The combined predicate is slightly less readable but avoids two filter calls.
What about Java 8 compatibility?
// Java 8: no isBlank(), use trim().isEmpty()
List<String> java8 = Arrays.stream(names)
.filter(Objects::nonNull)
.filter(s -> !s.trim().isEmpty())
.toList();
What about Predicate.not vs lambda negation?
// Predicate.not (Java 11) -- clean, readable
.filter(Predicate.not(String::isBlank))
// Lambda negation -- equivalent but less clean
.filter(s -> !s.isBlank())
// .negate() -- verbose
Predicate<String> notBlank = ((Predicate<String>) String::isBlank).negate();
What are common mistakes?
WRONG: Filtering nulls after isBlank.
WRONG: Using isEmpty() and missing whitespace-only strings.
// WRONG: " " passes isEmpty() check
Arrays.stream(names)
.filter(Objects::nonNull)
.filter(s -> !s.isEmpty()) // " " is NOT empty!
.toList(); // ["Rajesh", " ", "Priya", "Amit"] -- " " leaks through!
What should a senior engineer know?
- `isBlank()` uses `Character.isWhitespace()` internally, which handles Unicode whitespace including non-breaking spaces (`\u00A0`), tabs, and newlines. `trim()` only handles ASCII characters with code point <= 32. - For strict input validation, consider using `strip()` (Java 11, Unicode-aware) followed by `isEmpty()` as an alternative to `isBlank()`. - In parallel streams, both `filter(Objects::nonNull)` and `filter(Predicate.not(String::isBlank))` are stateless and safe.
Visual Overview
["Rajesh", null, "", "Priya", " ", null, "Amit"]
│
▼
filter(Objects::nonNull)
["Rajesh", "", "Priya", " ", "Amit"] (nulls removed)
│
▼
filter(Predicate.not(String::isBlank))
["Rajesh", "Priya", "Amit"] (empty + whitespace removed)
Key Takeaway
Removing nulls and empty strings uses filter(Objects::nonNull) followed by filter(Predicate.not(String::isBlank)). The order is critical: nonNull must come first because calling isBlank() on null throws NullPointerException.
String.isBlank() (Java 11) is strictly better than isEmpty() for cleaning because it catches whitespace-only strings like " " that isEmpty() misses. For Java 8 compatibility, use !s.trim().isEmpty() instead.
At National Bank of India, a CSV import of beneficiary names contains nulls, empty strings, and whitespace-only cells. The two-filter pattern discards all three, leaving only real names for validation.
Remember one sentence: filter nonNull first, then filter not-isBlank, and never call a string method on a potentially null reference.
---