let n = (param1) => someOperation(param1);
Fortunately Java introduced this in Java 8 but it isn’t identical, we’ll look at making our own lambda in Java and cover the steps to do so.
Creating a Function Interface
Firstly, Java is static and therefore cannot magically infer some dynamic type to run against for a lambda. Instead, they’ve provided us interfaces which can be lambda[ised]:
Utilising a Lambda
Now we just need to utilise our functional interface:
We create the variable to store our expression within, a.k.a., our lambda method reference and pass it a lambda implementation which is compliant with our single public abstract method signature. This one utilises generics, but there’s nothing stopping you hard-coding types either.
After which we use the reference to call the interface member, which uses our lambda implementation and computes our operation with our given operand.
What about scoping though?
In the above example, I’ve commented out modification. This is because any member variable accessed from the local method’s scope must be final or effectively final, i.e., it cannot be called for modification.
Fortunately, we can use field members:
So lambdas are just method declaration and implementation references?
Yup, by this logic, a functional interface only needs a reference to an implementation, and a lambda is just an implementation. Java 8 provides method references:
// :: denotes we're referencing a method
FunctionInterfaceStaticType name = Class::methodName;
And we can use one to access and fulfil our functional interface compliance too!
Consider the following:
Could be refactored to:
Note: The actual method name for this implementation doesn’t matter at all, could be named bobsburgers for all the JVM cares
Now this doesn’t only work for static members, but instance too:
That’s pretty much it honestly. But, wouldn’t it be great if we didn’t have to keep making functional interfaces every single time we want a lambda or reference for personal use and not part of some library?
Built in Functional Interfaces
Welp, Java has many built in functional interfaces already. Here’s a summary of each:
A predicate takes a single argument and returns a boolean:
Now on the actual functional interface itself, it has some cool methods for us to chain predicates together, such as logical and:
We can negate the value too:
We can present another predicate, and if it logically returns true, so does the final result:
Functions Functional Interface takes a single argument and returns a result of type T:
We can chain functions together using the value from the previous function:
A supplier returns a value:
A consumer consumes a parameter and returns nothing:
Consumers can also perform an andThen with another consumer:
Takes a single type argument and compares two given objects, returning an integer for the result:
Comparators have pretty wide range of utility functions which can be executed subsequently, I’d going to have to suggest the API for this: API Doc
Additional Function Interfaces
Bi Functional Interfaces
Any interface prefixed with Bi implies it takes two arguments, so, for example:
Function<Param Type, Return Type>
BiFunction<Param t1, Param t2, return t>
Working with Primitives
Functional Interfaces cannot accept primitives as their generic natively, to combat this issue, there are many, many built in primitive oriented function interfaces such as:
As you can imagine, all primitive types are supported and their work identical to their reference oriented counter parts.
Additionally we have the ‘To<Type>Bi<Function type>’ Functional interfaces, to allow us to accept two arguments and return a single primitive, akin to their reference type Bi counter parts.
And that concludes the Lambdas and method references article. You can reach me in my discord server.