I want to create Comparator
based on Enum.name()
which is inside a bean class:
List.of(new JobRsp(Job.MY), new JobRsp(Job.OUR), new JobRsp(Job.YOUR)).stream()
.sorted(__ -> __.getJob().name());
If I only needed Enum.order()
I could write sorted(Job::getJob)
.
Is it possible co compose zero args methods in functional style in Java? Something like:
FuncUtils.compose(Job::getJob, Enum::name)
Or probably even longer:
.sort(FuncUtils.chainGetters(ObjA::getB, ObjB::getC, ObjC::getD, ObjD::getE))
Imaginary chainGetters
might check for null
s.
I understand that Java doesn't allow variadic generics so there should be chainGetters
for each argument arity.
You have the default andThen
method in Function
interface that lets you chain functions.
Unfortunately there is no "clean" way to achieve the result, because to call a default method on a method reference you need to assign it, or cast it.
For example:
import static java.util.Comparator.comparing;
Function<Job, Enum> getJob = Job::getJob;
...
.sorted(comparing(getJob.andThen(Enum::name)))
Or:
.sorted(comparing( ((Function<Job, Enum>) Job::getJob).andThen(Enum::name) ))
So, it's cleaner to use a lambda expression using Comparator.comparing
to create the comparator:
...
.sorted(comparing(j -> j.getJob().name()))
The compose
utility method that you suggest could be also implemented with:
public static <A, B, C> Function<A, C> compose(Function<A, B> first, Function<B, C> second) {
return first.andThen(second);
}
So you could use:
.sorted(comparing( FuncUtils.compose(Job::getJob, Enum::name)))