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 nulls.
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)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With