Java › Functional Interfaces & Method References
How does the Predicate interface's default methods and(), or(), and negate() enable composing complex boolean conditions from simpler ones?
IntermediateAnswer
and(other) creates a composed predicate that's true only if both the original and the other predicate are true (with short-circuit evaluation, matching && semantics); or(other) is true if either is true (short-circuiting like ||); negate() inverts the predicate's result -- these default methods let you build complex, readable filtering conditions by composing small, well-named predicates together rather than writing one large, harder-to-read boolean expression inline.
Predicate<String> isLongEnough = s -> s.length() >= 8;
Predicate<String> hasDigit = s -> s.chars().anyMatch(Character::isDigit);
Predicate<String> hasUpperCase = s -> s.chars().anyMatch(Character::isUpperCase);
Predicate<String> isStrongPassword = isLongEnough.and(hasDigit).and(hasUpperCase);
System.out.println(isStrongPassword.test("Password1")); // trueReal-world example A password validation system composes several small, individually-named predicates (isLongEnough, hasDigit, hasUpperCase, hasSpecialChar) into one final isStrongPassword predicate using and(), making the overall validation logic self-documenting and each individual rule independently testable, rather than one large inline boolean expression.