Predicate in Java 8 with Examples

Predicate in Java 8: A predicate is a function that takes a single argument and returns a boolean value. In Java, the Predicate interface was introduced in version 1.8 specifically for this purpose, as part of the java.util.function package. This interface serves as a functional interface, designed with a single abstract method: test().

Predicate Interface

The Predicate interface is defined as follows:

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

This interface allows the use of lambda expressions, making it highly suitable for functional programming practices.

Example 1: Checking if an Integer is Even

Let’s illustrate this with a simple example of checking whether an integer is even:

Traditional Approach:

public boolean test(Integer i) {
    return i % 2 == 0;
}

Lambda Expression:

Predicate<Integer> isEven = i -> i % 2 == 0;
System.out.println(isEven.test(4)); // Output: true
System.out.println(isEven.test(7)); // Output: false

Complete Predicate Program Example:

import java.util.function.Predicate;

public class TestPredicate {
    public static void main(String[] args) {
        Predicate<Integer> isEven = i -> i % 2 == 0;
        System.out.println(isEven.test(4));  // Output: true
        System.out.println(isEven.test(7));  // Output: false
        // System.out.println(isEven.test(true)); // Compile-time error
    }
}

More Predicate Examples

Example 2: Checking String Length

Here’s how you can determine if the length of a string exceeds a specified length:

Predicate<String> isLengthGreaterThanFive = s -> s.length() > 5;
System.out.println(isLengthGreaterThanFive.test("Generate")); // Output: true
System.out.println(isLengthGreaterThanFive.test("Java"));     // Output: false

Example 3: Checking Collection Emptiness

You can also check if a collection is not empty using a predicate:

import java.util.Collection;
import java.util.function.Predicate;

Predicate<Collection<?>> isNotEmpty = c -> !c.isEmpty();

Combining Predicates

Predicates can be combined using logical operations such as and(), or(), and negate(). This allows for building more complex conditions.

Example 4: Combining Predicates

Here’s an example demonstrating how to combine predicates:

import java.util.function.Predicate;

public class CombinePredicates {
    public static void main(String[] args) {
        int[] numbers = {0, 5, 10, 15, 20, 25, 30};

        Predicate<Integer> isGreaterThan10 = i -> i > 10;
        Predicate<Integer> isOdd = i -> i % 2 != 0;

        System.out.println("Numbers greater than 10:");
        filterNumbers(isGreaterThan10, numbers);

        System.out.println("Odd numbers:");
        filterNumbers(isOdd, numbers);

        System.out.println("Numbers not greater than 10:");
        filterNumbers(isGreaterThan10.negate(), numbers);

        System.out.println("Numbers greater than 10 and odd:");
        filterNumbers(isGreaterThan10.and(isOdd), numbers);

        System.out.println("Numbers greater than 10 or odd:");
        filterNumbers(isGreaterThan10.or(isOdd), numbers);
    }

    public static void filterNumbers(Predicate<Integer> predicate, int[] numbers) {
        for (int number : numbers) {
            if (predicate.test(number)) {
                System.out.println(number);
            }
        }
    }
}

Predicate in Java 8: Using and(), or(), and negate() Methods

In Java programming, the Predicate interface from the java.util.function package offers convenient methods to combine and modify predicates, allowing developers to create more sophisticated conditions.

Example 1: Combining Predicates with and()

The and() method enables the combination of two predicates. It creates a new predicate that evaluates to true only if both original predicates return true.

import java.util.function.Predicate;

public class CombinePredicatesExample {
    public static void main(String[] args) {
        Predicate<Integer> isGreaterThan10 = i -> i > 10;
        Predicate<Integer> isEven = i -> i % 2 == 0;

        // Combined predicate: numbers greater than 10 and even
        Predicate<Integer> isGreaterThan10AndEven = isGreaterThan10.and(isEven);

        // Testing the combined predicate
        System.out.println("Combined Predicate Test:");
        System.out.println(isGreaterThan10AndEven.test(12)); // Output: true
        System.out.println(isGreaterThan10AndEven.test(7));  // Output: false
        System.out.println(isGreaterThan10AndEven.test(9));  // Output: false
    }
}

Example 2: Combining Predicates with or()

The or() method allows predicates to be combined so that the resulting predicate returns true if at least one of the original predicates evaluates to true.

import java.util.function.Predicate;

public class CombinePredicatesExample {
    public static void main(String[] args) {
        Predicate<Integer> isEven = i -> i % 2 == 0;
        Predicate<Integer> isDivisibleBy3 = i -> i % 3 == 0;

        // Combined predicate: numbers that are either even or divisible by 3
        Predicate<Integer> isEvenOrDivisibleBy3 = isEven.or(isDivisibleBy3);

        // Testing the combined predicate
        System.out.println("Combined Predicate Test:");
        System.out.println(isEvenOrDivisibleBy3.test(6));  // Output: true
        System.out.println(isEvenOrDivisibleBy3.test(9));  // Output: true
        System.out.println(isEvenOrDivisibleBy3.test(7));  // Output: false
    }
}

Example 3: Negating a Predicate with negate()

The negate() method returns a predicate that represents the logical negation (opposite) of the original predicate.

import java.util.function.Predicate;

public class NegatePredicateExample {
    public static void main(String[] args) {
        Predicate<Integer> isEven = i -> i % 2 == 0;

        // Negated predicate: numbers that are not even
        Predicate<Integer> isNotEven = isEven.negate();

        // Testing the negated predicate
        System.out.println("Negated Predicate Test:");
        System.out.println(isNotEven.test(3));  // Output: true
        System.out.println(isNotEven.test(6));  // Output: false
    }
}

and() Method: Combines two predicates so that both conditions must be true for the combined predicate to return true.

or() Method: Creates a predicate that returns true if either of the two predicates is true.

negate() Method: Returns a predicate that represents the logical negation (inverse) of the original predicate.

Best Practices for Using Predicate in Java 8

  1. Descriptive Names: Use descriptive variable names for predicates to enhance code readability (e.g., isEven, isLengthGreaterThanFive).
  2. Conciseness: Keep lambda expressions concise and avoid complex logic within them.
  3. Combination: Utilize and(), or(), and negate() methods to compose predicates for more refined conditions.
  4. Stream Operations: Predicates are commonly used in stream operations for filtering elements based on conditions.
  5. Null Handling: Consider null checks if predicates may encounter null values.
  6. Documentation: Document predicates, especially those with complex logic, to aid understanding for others and future reference.

Conclusion

Predicates in Java provide a powerful mechanism for testing conditions on objects, offering flexibility and efficiency in code design. By leveraging lambda expressions and method references, developers can write cleaner and more expressive code. Start incorporating predicates into your Java projects to streamline logic and improve maintainability.

Java 8 Quiz
Here is the link for the Java 8 quiz:
Click here

Related Articles:

Leave a Comment