Higher-order function is an essential part of the functional programming paradigm. We must have defined a lot of functions in any language where we pass either primitive types or an object as an argument and returns the same. These are normal functions or methods.
Then comes first-class functions. First-class functions are the functions that are treated as values. It means, those functions can be assigned to a variable and can be passed around as an argument.
And finally, comes higher-order functions. These are the functions that either takes one or more function as an argument or returns the function as a result.
The two things (First class function and higher-order function) are closely related, as it’s hard to imagine a language with first-class functions that would not also support higher-order functions, and conversely a language with higher-order functions but without first-class function support.
Before Java8, we used to pass a function to a function with the help of anonymous inner classes, but now we do that with the help of Lambdas.
Before Java 8:
After Java 8:
In the above example,
we are passing pathname -> pathname.getAbsolute().endsWith(“txt”) as an argument to listFiles().
Generally, a function has a body, a name, a parameter list, and a return type. The passed function here has a parameter list followed by an arrow ( -> ), and then the short body. The type of the parameter may be inferred by the Java compiler here and the return type is implicit. This function is anonymous; it has no name.
Rather than referring to these as anonymous functions, we call them lambda expressions.
Let’s understand the higher-order function in deep with some code examples:
Returns function as a result:
In the above example, checkIfStartsWith() returns Predicate.
In the above example, checkIfStartsWith() returns Function which takes 1 argument and returns the Predicate.
In the above example, getList() returns BiFunction which takes 2 arguments and returns the List.
Predicate, Function, and BiFunction are the functional interface that is used to write Lamda expression in the above examples.
Take the function as an argument:
In the above example, filter() is the higher-order function which takes a Predicate as an argument.
In the above example, filter() is the higher-order function that takes Function as an argument.
In the above example, getList() is the higher-order function that takes Predicate as an argument.
We have taken the examples only for 3 different Functional Interfaces, but there are more predefined functional interfaces such as Supplier, Consumer, etc and even we can define our own custom Functional interface and can use that to define Lambda expression.
So that is all about higher-order function. I hope this blog will help you to understand the higher-order function in Java which is enabled in Java 8 with the help of Lamdas and Functional interfaces.