Sometimes it is usefull to name lambdas. Especially when you pass them around as parameter.
A realy simple example is
public class Main {
public static void main(String[] args) {
Predicate<String> p = nameIt("isNotEmpty", (s) -> !s.trim().isEmpty());
maybePrint("Hello", p);
maybePrint(" ", p);
}
static <T> void maybePrint(T s, Predicate<T> pred) {
if (pred.test(s)) {
System.out.println(s.toString());
} else {
System.err.println(pred + " says no to \"" + s + "\"");
}
}
}
It would be nice to have some functionality by the jvm to name lambdas without loosing the great performance optimizations behind the scenes.
Somethink like this would be fine for me:
Predicate<String> p = nameIt("isNotEmpty", (s) -> !s.trim().isEmpty());
This is my solution(inspired from the solution of andersschuller at https://stackoverflow.com/a/23705160/1325574) for the problem. There maybe some corner cases(Classloading) where this implementation does not work, but for the most simple cases it works.
I have created a small performance test of this with my limited jmh knowledge: https://gist.github.com/picpromusic/4b19c718bec5a652731a65c7720ac5f8
The "Named"-results are measured for the implementation of the answer of @stuartmarks Naming(toString) Lambda-Expressions for Debugging purpose
As you can see it is roughly 2 times slower than using an unnamed lambda. So be carefull in setting -DnamedLambdasEnabled=true. Interessting for me is that it is surprisingly expensive to call toString on an Real-lambda. Maybe someone can explain that, or my jmh-test is stupid.
Here is the code:
Do you have other solutions? Maybe something that does not have performance implications?
Here's an alternative that comes to mind:
This seems pretty simple. Although I haven't benchmarked it, it seems like it ought to be pretty fast. It adds a single object and one method call, and it avoids boxing/unboxing overhead.
The drawback is that you have to write a little function like this for every functional interface for which you want to provide named instances.