Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java utility method to combine two lambdas?

In .NET, there's an easy way to combine two delegates (.NET's version of a lambda).

Basically, you have:

LambdaType f1 = (a, b) => doSomething(a, b);
LambdaType f2 = (a, b) => doSomethingElse(a, b);
LambdaType combined = System.Delegate.Combine(f1, f2); 
// combined is equiv to: (a, b) => { f1.invoke(a, b); f2.invoke(a, b);};

Is there something like this in Java to combine two lambdas? Nothing comes to mind. It'd be a nice little utility, although it's honestly not too hard to define a second lambda that just invokes two (or more).

like image 985
Joseph Nields Avatar asked Dec 05 '22 20:12

Joseph Nields


2 Answers

Are you talking about Java 8 lambdas? Because such utilities exist, for example:

Predicate<Foo> pred1 = f -> true; 
Predicate<Foo> pred2 = pred1.and(f -> false);

or

Function<Int,Int> func1 = x -> x + 1;
Function<Int,Int> func2 = func1.andThen(x -> x*2);

You should take a look at java.util.function package because you will likely find the feature already available.

In your specific example you are not composing two functions, indeed, functionally speaking, you can't compose two functions that accept two arguments and return one argument (or void).

This because you are lacking a requirement: the codomain of the first function must correspond to the domain of the second function, otherwise composition can't be done.

What you are really doing here is sequentially calling two unrelated functions with same arguments. This problem can be solved by doing exactly the same thing:

BiConsumer<Foo,Bar> combination = (f,b) -> { doSomething(f,b); doSomethingElse(f,b); };
like image 150
Jack Avatar answered Dec 25 '22 04:12

Jack


Since your request seem to incorporate functions which do not return anything, the appropriate Java 8 type would be BiConsumer. This allows you to do as you want:

BiConsumer<A,B> f1=(a,b) -> doSomething(a,b);
BiConsumer<A,B> f2=(a,b) -> doSomethingElse(a,b);
BiConsumer<A,B> combined = f1.andThen(f2);

This relies on the function type providing the factory methods for combined functions, rather than allowing arbitrary combinations, on the other hand, this allows to have meaningful combinations, like and/or for Predicates which do something useful and understandable instead of just invoking the code of both functions and returning an arbitrary result.

like image 24
Holger Avatar answered Dec 25 '22 02:12

Holger