Java – Declaring lambdas in Java8

functional programmingjava

What would be the best practice to declare lambdas in Java8 code? How it was designed to be used?

For example, let's say that we have a method that accept a Function. I want to provide function implementation that can be reusable. So I can do this:

[A] Implement a Function interface:

public class Foo implements Function<A,B> {
    public B apply(A a) {...}
}
...
useFunction(new Foo());

[B] Declare Function as lambda in some static field:

public interface Foo {
    Function<A,B> bar = it -> { ....}
}
...
useFunction(Foo.bar);

[C] Use method reference:

public class Foo {
    public static B bar(A a) {...}
}
...
useFunction(Foo::bar);

Until functional programing in java8, I tried not to pollute code with statics. However, now I am somehow 'forced' to use statics (or global singletons) for storing reusable lambdas.

EDIT

I have code that returns the following on several places:

return CompletableFuture.supplyAsync(() -> {
...
}
.exceptionally(FooExceptionWrapper::wrap);

As you see, I want to share the wrapper (that is a Function) instances, and yet to remain fluent with the code. There are many ways how we can share this.

If I create new instance every time (like in A) then we are going to create new instance on every call, which is fine; yet GC is going to be called more frequently. I can instead create a singleton and since this is a Function, sharing it across the threads is not going to be a problem. So I might store it in some variable. Now, I would like to put the handling code out of this class (simple to reduce the size and the responsibility of the class). So I use approach A – but still want to see if there is more 'proper' way for this. There are not many java8 projects out there, and lot of people simple use static fields (like in B); Im just questioning all that.

Best Answer

If you expect a function to be reused or shared, make it a method and use a method reference. If you just need a short, throwaway piece of logic, make it a lambda. Explicitly creating instances of a functional interface has no advantages and has disadvantages:

  • Less idiomatic
  • More boilerplate
  • You commit to types up front, while a method reference or lambda will match any functional interface with the right signature.
  • Most likely less efficient