Over het algemeen betekent predikaat een verklaring die bepaalt of een waarde waar of onwaar kan zijn. Bij het programmeren bedoelen predikaten functies met één argument die een booleaanse waarde retourneren. Functional Interface Predicate is gerealiseerd in Java 8. "Functioneel" betekent dat het slechts één abstracte methode bevat. Het accepteert een argument en retourneert een boolean. In Java worden functionele interfaces gebruikt voor het afhandelen van Lambda-expressies, constructors en methodereferenties. Gewoonlijk wordt Java 8 Predicate gebruikt om een ​​filter toe te passen op een verzameling objecten. Laten we eens kijken naar de belangrijkste toepassingen en veelgebruikte methoden, en enkele oefenproblemen oplossen. Java-predikaat met voorbeelden - 1

Waarom ontwikkelaars Predicate gebruiken

In principe kunnen ontwikkelaars predikaten gebruiken voor alle taken die te maken hebben met het evalueren van items op basis van vooraf gedefinieerde criteria en het retourneren van een booleaanse waarde. Hier zijn de voorbeelden van eenvoudige taken die ontwikkelaars uitvoeren met behulp van predikaten:
  • Een reeks gehele getallen filteren.
  • Sorteren van lijsten door ervoor te zorgen dat de gegevens voldoen aan verschillende vooraf gedefinieerde voorwaarden (bijv. het organiseren van een reeks artikelen door prijs- en gewichtsvoorwaarden in te stellen).
  • Hulpprogrammapakketten gebruiken bij gelijktijdig programmeren.
Predicaten zijn een belangrijk kenmerk bij het testen van software. De functionele interface maakt het gemakkelijker om eenheden te scheiden voor testen, verbetert de leesbaarheid en de beheersbaarheid van de app-code.

Predikaatsyntaxis in Java

java.util.function.Predicate is geïntroduceerd in Java 8 als een alternatieve manier om beoordelingsvertoningen in Lambda te verwerken. De standaardweergave van de interface is Predicate<T> , waarbij T een enkel argument is dat een booleaanse waarde retourneert. Java-predicaten hebben een functionele (abstracte) methode test(Object) die dit predikaat op een bepaald object evalueert.

@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
Hier is een voorbeeld van het schrijven van een eenvoudig predikaat dat gehele getallen filtert op basis van voorwaarden "groter dan", "kleiner dan".

// An example of a simple Java predicate
  
import java.util.function.Predicate; 
public class PredicateExample { 
    public static void main(String[] args) 
    { 
        // Creating predicate 
        Predicate<Integer> lesserThan = i -> (i < 18);  
  
        // Calling Predicate method 
        System.out.println(lesserThan.test(10));  
    }
}
De uitvoer is waar omdat 10 < 18. Nog een voorbeeld met Predicate in filter() . Predikaat helpt om alle volwassenen uit de lijst met leeftijden te filteren.

  import java.util.List;
  import java.util.function.Predicate;

  public class PredicateExample {
      public static void main(String[] args) {
          List<Integer> ages = List.of(17, 18, 19, 28, 18, 28, 46, 7, 8, 9, 21, 12);
          NotLessThan18<Integer> isAdult = new NotLessThan18<>();
          ages.stream().filter(isAdult).forEach(System.out::println);
      }
  }



class NotLessThan18<E> implements Predicate<Integer> {

      @Override
      public boolean test(Integer v) {
          Integer ADULT = 18;
          return v >= ADULT;
      }
  }
De uitvoer is:
18 19 28 18 28 46 21

Java 8 Predikaatmethoden

De Predicate Interface heeft een handvol methoden.
  • booleaanse test(T t) evalueert het predikaat op het gegeven argument.
  • default Predikaat<T> and(Predikaat<? super T> andere) retourneert een predikaat dat een kortgesloten logische AND vertegenwoordigt van dit predikaat en een ander.
  • default Predikaat<T> of retourneert een samengesteld predikaat dat een kortgesloten logische OR vertegenwoordigt van dit predikaat en een ander.
  • default Predikaat<T> negate() geeft een predikaat terug dat logisch tegengesteld is aan dit predikaat.
  • default Predicate<T> isEqual(Object targetRef) retourneert een testresultaat als twee argumenten gelijk zijn volgens Objects.equals(Object, Object) .

booleaanse test(T t)

Dit is een functionele methode voor Java-predikaten die evalueert of een bepaald argument al dan niet voldoet aan de voorwaarde van een predikaat. Voorbeeld: hier maken we een predikaat volwassene aan voor iedereen die 18 jaar of ouder is. test() haalt een geheel getal op en controleert deze.

import java.util.function.Predicate;
public class PredicateTestTest {
   public static void main(String[] args) {
       Predicate<Integer> adult = i -> i >= 18;
       System.out.println(adult.test(12));
       System.out.println(adult.test(19));
       System.out.println(adult.test(21));
   }
}
Wat zal de uitvoer van de bovenstaande code zijn? In het eerste geval, aangezien 12 kleiner is dan 18, zal het onwaar zijn. Wat het tweede en het derde scenario betreft, is aan de voorwaarden voldaan, zodat het rendement waar zal zijn.
onwaar waar waar

standaard Predikaat.en()

Deze methode vertegenwoordigt de operator "en". Daarom, als een van de gegeven predicaten niet voldoet aan een gestelde voorwaarde, krijgt een ander geen waardering. Voorbeeld: Laten we predikaten samenstellen in Java en alle mensen filteren die al volwassen zijn maar jonger dan 65 jaar met behulp van and() . Laten we predicate.add () gebruiken en een java-predikaat schrijven met lambda voor deze voorwaarden: Als de voorwaarde waar is, retourneert de app de volgende verklaring:

import java.util.function.Predicate;

   public class PredicateDemo {
       public static void main(String[] args) {
           Predicate<Integer> adultYet = i -> i >= 18;
           Predicate<Integer> adultStill = i -> i < 65;
           System.out.println(adultYet.and(adultStill).test(5));
           System.out.println(adultYet.and(adultStill).test(38));
           System.out.println(adultYet.and(adultStill).test(90));
       }
   }
De uitvoer is:
onwaar waar onwaar

standaard Predikaat.or()

De methode Predicate.or() vertegenwoordigt de operator 'OF'. Dit betekent dat de voorwaarde waar blijft, zelfs als een van de twee predikaten waar is en de andere onwaar. Voorbeeld: laten we nu tekenreeksen evalueren. Probeer de OR-methode te gebruiken om alle woordgroepen te doorzoeken die subtekenreeks "mijn" of "krijt" bevatten.

import java.util.function.Predicate;

  public class PredicateDemo2 {
      public static void main(String[] args) {
          Predicate<String> containsA = t -> t.contains("crayon");
          Predicate<String> containsB = t -> t.contains("my");
          System.out.println(containsA.or(containsB).test("here is my crayon"));
          System.out.println(containsA.or(containsB).test("here is my pencil"));
          System.out.println(containsA.or(containsB).test("here is John's crayon"));
          System.out.println(containsA.or(containsB).test("here is John's pencil"));
      }
  }
De uitvoer is:
waar waar waar onwaar

standaard Predikaat ontkennen()

negate() methode wordt gebruikt om alle waarden te verzamelen die niet voldoen aan vooraf gedefinieerde criteria. Voorbeeld: als u de klasse "Tomaten" wilt doorzoeken en alle vermeldingen wilt vinden die niet "Rood" zijn, kunt u een predikaat schrijven en snel door de hele reeks bladeren. Probeer de code voor deze zelf te schrijven en vergelijk deze met de oplossing als u klaar bent.

import java.util.function.Predicate;

public class PredicateDemo3 {
public static void main(String[] args) {
 Predicate<Integer> adult = i -> i >= 18;
System.out.println(adult.negate().test(7));  System.out.println(adult.negate().test(19))
  }
   }
De uitvoer is:
waar onwaar

statisch Predicaat isGelijk(Object targetRef)

Deze methode is erg handig als u wilt bepalen of twee objecten gelijk zijn aan een waarde die is gedefinieerd als een parameter van Objects.equals(). Deze methode is vooral handig als u vergelijkbare testresultaten moet vergelijken. Voorbeeld: stel dat u twee rijen peren vergelijkt en u wilt zeker weten of beide vruchten hebben met een standaardgewicht en kleur. In dit geval is static Predicate isEqual(Object targetRef) precies de methode die u nodig hebt. Laten we eens kijken hoe isEqual de gelijkheid van twee strings controleert:

import java.util.function.Predicate;

public class PredicateDemo2 {
   public static void main(String[] args) {
       Predicate<String> i = Predicate.isEqual("here is my crayon");
       System.out.println(i.test("here is my pencil"));
       System.out.println(i.test("here is my crayon"));
   }
}
Als een object dat u analyseert, voldoet aan de standaardvoorwaarden, retourneert de functie true. De uitvoer is:
onwaar waar

Java IntPredicate

Java IntPredicate is een functionele interface, dus u kunt het gebruiken als toewijzingsdoel voor een lambda-expressie of methodereferentie. IntPredicate werkt op een geheel getal en retourneert een predikaatwaarde op basis van een voorwaarde. Net als Predicate Interface heeft IntPredicate ook test() , and() , negate() of () methoden. Hier is een voorbeeld van IntPredicate. Het filtert ook alle volwassenen (18 of meer) uit de reeks.

import java.util.Arrays;
import java.util.function.IntPredicate;

public class IntPredicateExample {

   public static void main(String[] args) {

       int[] ages = { 18, 28, 18, 46, 90, 45, 2, 3, 1, 5, 7, 21, 12 };

       IntPredicate p = n -> n >= 18;

       Arrays.stream(ages).filter(p).forEach(System.out::println);
   }
}
De uitvoer is:
18 28 18 46 90 45 21

Schrijven van schone predicaten in Java

Java-predicaten zijn zeer functioneel en leuk om mee te werken. Tenzij u zich echter bewust bent van de invloed van lambda-expressies die u schrijft op de code, bestaat het risico dat de onderhoudbaarheid van de code wordt verminderd met rommelige predikaten. Hier zijn een paar eenvoudige praktijken die u zullen helpen ervoor te zorgen dat uw functionele interfaces gemakkelijk te beheren en te lezen zijn.
  • Herhaal uzelf niet - stel predikaten niet meer dan eens samen met Java met herhaalde waarden, methoden en voorwaarden. Op deze manier verspil je je productieve tijd en maak je de code rommelig.
  • Scheid predicaten van de app-code om testbaarheid te garanderen. Anders dan dat, maak een testschema voor predikaateenheden en houd je eraan.
  • Gebruik import- en compositiepatronen om ervoor te zorgen dat je lessen niet te groot worden en eenvoudig te beheren blijven.
  • Overweeg om Java-predikaten naar Helper-klassen te verplaatsen — op deze manier verbetert u de herbruikbaarheid van uw code en vereenvoudigt u het onderhoud.
  • Leesbaarheid — geef waar mogelijk de voorkeur aan uitspraken van één regel boven complexe predicaten. Het kan verleidelijk zijn om te pronken met uw begrip van complexe functionele interfaces. Maar als het op onderhoud aankomt, is minder meer.