This is a term you may not have heard. Although the term isn’t used often, these kinds of functions are common. We use higher-order functions all the time when we use streams.
Higher-order functions are functions that either accept other functions as arguments, or return a function as a result.
The result of one higher-order function can be used as the input to another higher-order function. Any time we pass a lambda expression to a method, that method is a higher-order function.
Java 8 supports higher-order functions, along with lambda expressions and functional interfaces. Stream processing uses lambda expressions and higher-order functions extensively.
Example of a higher-order function
My previous post discussed the standard functional interfaces in the java.util.function
package. One of the most commonly used functional interfaces is the Predicate
.
A Predicate
represents a function that takes one argument and returns a boolean
value. The functional method is boolean test(Object)
. So the interface looks like this (omitting default and static methods):
@FunctionalInterface public interface Predicate{ public boolean test(T t); }
We create Predicate
variables and assign lambda expressions to them as follows:
Predicatepred1 = e -> e.getAge() < 65; Predicate pred2 = e -> e.getSalary() > 10000.0; // using a default method of Predicate Predicate pred3 = pred1.and(pred2);
But what about the test()
method? We never create one. And we do not call it in the normal course of programming, for example, when processing streams.
// create and populate a list with employee objects... Listlist = new ArrayList<>(); ... // use a stream to process the list
list.stream().filter(p1).filter(p2).forEach( e -> System.out.println(e));
This filter()
method is a higher-order function that takes a Predicate
as a parameter. The filter()
method is applied to each element to check if it should be included in the stream. Inside the filter()
method, the test()
method of the Predicate
is called, and the lambda expression is executed.
Writing our own higher-order function
Let’s try it out by creating our own higher-order function that takes a Predicate
:
public void runPredicate(Employee e, Predicatep) { if (p.test(e) == true) System.out.println("True"); else System.out.println("False"); }
We can call the higher-order function as follows:
Employee e1 = new Employee("Harriet", 31, Person.FEMALE, 30_000.0);
Predicatepred1 = e -> e.getAge() < 65; Predicate pred2 = e -> e.getSalary() > 10000.0; // using a default method of Predicate Predicate pred3 = pred1.and(pred2); runPredicate(e1, pred1); runPredicate(e1, pred2); runPredicate(e1, pred3);
There it is! Simple as that!
I’m always interested in your opinion, so please leave a comment. Your feedback helps me write tips that help you.
1 thought on “Higher-order Functions in Java”
Thanks for this post .