January 18, 2019

How to Implement java.util.function.DoublePredicate’s function – test, and, or and negate in java

This code should run in java 11 and above. It definitely needs – above java 8. Few things will work in java 9 or 10. But, code should successfully run in java 11 and above. Because, I am running java 11.

So, In this episode of java wonderland, we are going to implement java.util.function.BinaryPredicate.  Those who don’t know, this is a Functional Interface. You can follow the link to know more.

What are we gonna do here? We are going to create predicates, i.e objects of java.util.function.BinaryPredicate, to test presence of double values in a list and a map.

We will create more predicates, using the two predicates, that I just mentioned above, i.e presence of a double in a list and a map.

This interface comes with four methods, out of those four – test() method is an abstract method. This is where our code gets hooked in this interface.

  1. boolean test(double testValue) :- You pass a double value, and java run time executes the code in this method block. And returns true or false;
  2. default DoublePredicate and(DoublePredicae other) :- It executes the other  predicate after the predicate, which calls this method. And it will return true – if both the predicates return true.
  3. default DoublePredicate or(DoublePredicate other) :- It executes the other predicate after the caller predicate. This method returns true – if anyone of the predicate returns true.
  4. default DoublePredicate negate() :- It simply returns a new predicate, which is logically opposite of the calling predicate.

Things that we are gonna need for this testing.

A list full of double values. 

java.util.List<Double> listOfDouble = java.util.List.of(12.1, 10.0, 17.8);

A map full of double-value as the key. Here the values are not really important.

java.util.Map<Double, String> mapOfDoubleToString = java.util.Map.of(12.1, "12.1 in string",
                                                                             100.1, "one hundered and one");

A utility method which runs our tests.

private static void runTests(Double checkValue, java.util.Map<String, DoublePredicate> nameToDoublePredicateMap) {
        out.println("---------Running Test For "+ checkValue +"---------");
        DoublePredicate predicate = null;
        for(String predicateName : nameToDoublePredicateMap.keySet()) {
            predicate = nameToDoublePredicateMap.get(predicateName);
            out.print("Run Test on " + predicateName + " - ");
            out.println(predicate.test(checkValue));
        }
        out.println("---------Test Finished--------");
}

Here is our lambdas.

This lambda checks for the presence of a double value in the list.

//Check if the input element is present in the list                                                                                                                                                  
DoublePredicate isPresentInList = listOfDouble::contains;

This lambda checks for presence of a double value in the map.

//Check if the input element is present in the map                                                                                                                                                   
DoublePredicate isPresentInMap = mapOfDoubleToString::containsKey;

Using negate() — 

This lambda checks for absence of double value in list. Look closely, we are using  isPresentInList to create a new predicate.

//Creating a DoublePredicate, which is opposite of predicate which checks for presence of element in the list                                                                                        
DoublePredicate isAbsentInList = isPresentInList.negate();

This lambda checks for absence of double value in a map. We are using isPresentInmap to create new predicate.

//Creating a DoublePredicate, which is opposite of predicate which checks for presence of element in the map                                                                                         
DoublePredicate isAbsentInMap = isPresentInMap.negate();

Using and() —

Check element is present in both list and map

//Check - If element is present in both List and map                                                                                                                                                 
DoublePredicate isPresentInListAndMap = isPresentInList.and(isPresentInMap);

Check element is absent in both list and map

//Check - not present in both list and map                                                                                                                                                           
DoublePredicate isAbsentInListAndMap = isAbsentInList.and(isAbsentInMap);

Using or() —

Check element is present in any one of the list or map

//Check - If element is present in either list or map                                                                                                                                                
DoublePredicate isPresentInListOrMap = isPresentInList.or(isPresentInMap);

Now, we are going to need a container, which will provide sufficient information during test runs. It will help us identify the lambdas run by us.

We are going to create a map.

java.util.Map<String, DoublePredicate> nameToDoublePredicateMap = java.util.Map.of("isPresentInList", isPresentInList,
                                                                                           "isPresentInMap", isPresentInMap,
                                                                                           "isAbsentInList", isAbsentInList,
                                                                                           "isAbsentInMap", isAbsentInMap,
                                                                                           "isPresentInListAndMap", isPresentInListAndMap,
                                                                                           "isPresentInListOrMap", isPresentInListOrMap,
                                                                                        "isAbsentInListAndMap", isAbsentInListAndMap);

It contains the name of the lambda in string and the lambda itself as the value.

We will run our test on three values,

  1. 10.0 -> which is present in list, but absent in map
  2. 12.1 -> which is present in both list and map
  3. 19.0 -> which is absent in both list and map

Ok then.. let us run the tests.

runTests(12.1, nameToDoublePredicateMap);

runTests(10.0, nameToDoublePredicateMap);

runTests(19.0, nameToDoublePredicateMap);

Here is the output for 12.1.

---------Running Test For 12.1---------
Run Test on isPresentInList - true
Run Test on isPresentInMap - true
Run Test on isPresentInListAndMap - true
Run Test on isAbsentInListAndMap - false
Run Test on isAbsentInList - false
Run Test on isAbsentInMap - false
Run Test on isPresentInListOrMap - true
---------Test Finished--------

Here is the output for 10.0.

---------Running Test For 10.0---------
Run Test on isPresentInList - true
Run Test on isPresentInMap - false
Run Test on isPresentInListAndMap - false
Run Test on isAbsentInListAndMap - false
Run Test on isAbsentInList - false
Run Test on isAbsentInMap - true
Run Test on isPresentInListOrMap - true
---------Test Finished--------

Here is the output for 19.0.

--------Running Test For 19.0---------
Run Test on isPresentInList - false
Run Test on isPresentInMap - false
Run Test on isPresentInListAndMap - false
Run Test on isAbsentInListAndMap - true
Run Test on isAbsentInList - true
Run Test on isAbsentInMap - true
Run Test on isPresentInListOrMap - false
---------Test Finished--------

You can go through the output to learn, if my lambdas are producing right result or not.

Here is the complete code.

import java.util.function.DoublePredicate;
import static java.lang.System.out;

public class DoublePredicateTest {
    public static void main(String ... args) {
        java.util.List<Double> listOfDouble = java.util.List.of(12.1, 10.0, 17.8);
        java.util.Map<Double, String> mapOfDoubleToString = java.util.Map.of(12.1, "12.1 in string",
                                                                             100.1, "one hundered and one");

        //Check if the input element is present in the list                                                                                                                                                                                                             
        DoublePredicate isPresentInList = listOfDouble::contains;

        //Check if the input element is present in the map                                                                                                                                                                                                              
        DoublePredicate isPresentInMap = mapOfDoubleToString::containsKey;

        //Creating a DoublePredicate, which is opposite of predicate which checks for presence of element in the list                                                                                                                                                   
        DoublePredicate isAbsentInList = isPresentInList.negate();

        //Creating a DoublePredicate, which is opposite of predicate which checks for presence of element in the map                                                                                                                                                    
        DoublePredicate isAbsentInMap = isPresentInMap.negate();

        //Check - If element is present in both List and map                                                                                                                                                                                                            
        DoublePredicate isPresentInListAndMap = isPresentInList.and(isPresentInMap);

        //Check - If element is present in either list or map                                                                                                                                                                                                           
        DoublePredicate isPresentInListOrMap = isPresentInList.or(isPresentInMap);

        //Check - not present in both list and map                                                                                                                                                                                                                      
        DoublePredicate isAbsentInListAndMap = isAbsentInList.and(isAbsentInMap);

        java.util.Map<String, DoublePredicate> nameToDoublePredicateMap = java.util.Map.of("isPresentInList", isPresentInList,
                                                                                           "isPresentInMap", isPresentInMap,
                                                                                           "isAbsentInList", isAbsentInList,
                                                                                           "isAbsentInMap", isAbsentInMap,
                                                                                           "isPresentInListAndMap", isPresentInListAndMap,
                                                                                           "isPresentInListOrMap", isPresentInListOrMap,
                                                                                        "isAbsentInListAndMap", isAbsentInListAndMap);

        runTests(12.1, nameToDoublePredicateMap);

        runTests(10.0, nameToDoublePredicateMap);

        runTests(19.0, nameToDoublePredicateMap);


    }

    private static void runTests(Double checkValue, java.util.Map<String, DoublePredicate> nameToDoublePredicateMap) {
        out.println("---------Running Test For "+ checkValue +"---------");
        DoublePredicate predicate = null;
        for(String predicateName : nameToDoublePredicateMap.keySet()) {
            predicate = nameToDoublePredicateMap.get(predicateName);
            out.print("Run Test on " + predicateName + " - ");
            out.println(predicate.test(checkValue));
        }
        out.println("---------Test Finished--------");
    }
}

Complete Output

---------Running Test For 12.1---------
Run Test on isPresentInList - true
Run Test on isPresentInMap - true
Run Test on isPresentInListAndMap - true
Run Test on isAbsentInListAndMap - false
Run Test on isAbsentInList - false
Run Test on isAbsentInMap - false
Run Test on isPresentInListOrMap - true
---------Test Finished--------
---------Running Test For 10.0---------
Run Test on isPresentInList - true
Run Test on isPresentInMap - false
Run Test on isPresentInListAndMap - false
Run Test on isAbsentInListAndMap - false
Run Test on isAbsentInList - false
Run Test on isAbsentInMap - true
Run Test on isPresentInListOrMap - true
---------Test Finished--------
---------Running Test For 19.0---------
Run Test on isPresentInList - false
Run Test on isPresentInMap - false
Run Test on isPresentInListAndMap - false
Run Test on isAbsentInListAndMap - true
Run Test on isAbsentInList - true
Run Test on isAbsentInMap - true
Run Test on isPresentInListOrMap - false
---------Test Finished--------