Search code examples
javaooplambdajava-8predicate

Predicates in Java 8


I have a program that analyzes text for certain attributes. The basic structure of the code is the same for all attributes it only varies in one line: webDataField.containsAttributeXYZ(); as seen here:

for (int index = 0; index < fields.size(); index++) {
    WebDataField webDataField = fields.get(index);
    boolean expectedCondition = webDataField.containsAttributeXYZ(); // Varies at this line..

    Double score = evaluateBooleanCondition(actualCondition, expectedCondition);

    WebDataFields fieldName = webDataField.getFieldName();
    ...
}

Instead of writing the same code for each condition (& repeating myself in code) I'd like to write the main body of the code once and pass the condition (which evaluates to true or false) to the method.

I am new to Java Predicate but if I understand correctly this is exactly the function of predicates in Java.

Does this force me to write each condition in its own class and then have that class implement the Predicate interface?

If so, the function (which is previously declared in a class that contains similar functions) will need to be converted to something like:

class ContainsAttributeXYZ implements Predicate<Boolean>

This would cause the code to become disoriented and trigger a large increase in the number of classes in the program (as every function needs to be converted into a class)

Or did I misunderstand something about how Predicates work in Java? Is there another way of doing this?

Thanks


Solution

  • Here is an example method that takes a Predicate as an argument:

    void processFields(List<WebDataField> fields, Predicate<WebDataField> predicate) {
        for (WebDataField webDataField : fields) {
            boolean expectedCondition = predicate.test(webDataField);
        }
    }
    

    and you would call it by passing a method reference, like this:

    processFields(fields, WebDataField::containsAttributeXYZ);
    processFields(fields, WebDataField::containsAttributeABC);
    

    Where containsAttributeXYZ and containsAttributeABC are methods of WebDataField class that return boolean. Or you can create a lambda inline without modifying WebDataField. E.g. :

    processFields(fields, w -> w.getFieldName().length() > 5);
    

    You don't need to create a class that implements Predicate