W tym wpisie zajmiemy się interfejsem funkcjonalnym Predicate, który sam w sobie posiada dodatkowo kilka defaultowych metod. Predicate jest bardzo prosty i nie kryje w sobie żadnej większej tajemnicy. Jego zadaniem jest wykonywanie operacji logicznych.

Tak wygląda Predicate :

@FunctionalInterface
interface Predicate<T> {
​
  /**
   * Testuje podany argument i zwraca wartość boolean
   */
  boolean test(T t);
​
  /**
   * Sprawdza warunki wyrażeniem logicznym AND
   */
  default java.util.function.Predicate<T> and(java.util.function.Predicate<? super T> other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) && other.test(t);
  }
​
  /**
   * Sprawdza warunek i zwraca jego zaprzeczenie
   */
  default java.util.function.Predicate<T> negate() {
    return (t) -> !test(t);
  }
​
  /**
   * Sprawdza warunki wyrażeniem logicznym OR
   */
  default java.util.function.Predicate<T> or(java.util.function.Predicate<? super T> other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) || other.test(t);
  }
​
  /**
   * Wykonuje equal na przesłanym obiekcie
   */
  static <T> java.util.function.Predicate<T> isEqual(Object targetRef) {
    return (null == targetRef)
      ? Objects::isNull
      : object -> targetRef.equals(object);
  }
}

Przykład metody test. Tworzymy sobie obiekt book, który zawiera takie pola jak cena i rodzaj okładki. Tworzymy wyrażenie lambda, której zadaniem jest sprawdzenie czy cena jest wyższa niż 29.99.

    Book book = new Book(39.99, "twarda");
    Predicate<Book> checkPrice = book1 -> book1.price > 29.99;
​
    if (checkPrice.test(book)) {
      System.out.println("Drogo!");
    }

Wynik:

Drogo!

W tym przykładzie metody and dokładamy kolejne wyrażenie lambda, sprawdzające rodzaj okładki. Metodą and sprawdzamy obiekt book za pomocą obu wyrażeń lambda.

 Predicate<Book> checkCover = book2 -> book2.cover.equals("twarda");
​
    if (checkCover.and(checkPrice).test(book)) {
      System.out.println("Tanio!");
    }

Wynik:

Tanio!

Metoda or działa podobnie jak end ale tym razem na wyrażeniu OR

   if (checkCover.or(checkPrice).test(book)) {
      System.out.println("Tanio lub drogo!");
    }

Wynik:

Tanio lub drogo!

Metoda negate wykonuje negację zwracanego wyniku naszej lambdy checkPrice.

 if (!checkPrice.negate().test(book)) {
      System.out.println("A jenak tanio!");
    }

Wynik:

A jenak tanio!

Ostatnią metodą jest statyczna metoda isEqual sprawdzająca czy obiekty są takie same:

    Predicate<Book> i = Predicate.isEqual(new Book(39.99, "twarda"));
    System.out.println("Czy ta sama książka? " + i.test(book));

Wynik:

Czy ta sama książka? true

I to tyle, dalej eksperymentujcie sami 🙂