Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default andThen() method in BiFunction interface

There's a default method andThen() in the BiFunction interface (java.util.function package).

default <V> BiFunction<T,U,V> andThen(Function<? super R,? extends V> after)

The documentation says:

Returns a composed function that first applies this function to its input, and then applies the after function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the composed function.

It's little confusing to understand what the explanation means. As per my understanding, a composed function is returned when the default andThen() method is invoked. This composed function is invoked on the types T and U that returns the type V. Finally, there's and after function that is invoked on the types R and V.

What's the need of this method? How does it actually fit in the picture?

like image 324
mark42inbound Avatar asked Apr 28 '18 08:04

mark42inbound


People also ask

What are the methods of BiFunction interface?

The BiFunction interface consists of the following two functions: This method applies the given function to the arguments. Parameters: This method takes two parameters: Returns: This method returns the function result which is of type R. Below is the code to illustrate apply () method:

What is BiFunction functional interface in Java 8?

We're probably most familiar with the single-parameter Java 8 functional interfaces like Function, Predicate, and Consumer. In this tutorial, we're going to look at functional interfaces that use two parameters. Such functions are called binary functions and are represented in Java with the BiFunction functional interface. 2.

What is a BiFunction in Python?

It represents a function which takes in two arguments and produces a result. Hence this functional interface which takes in 3 parameters namely:- The lambda expression assigned to an object of BiFunction type is used to define its apply () which eventually applies the given function on the arguments.

What does the'after'function do in a BiFunction?

In other words the 'after' function maps the return value of this BiFunction<T, U, R> from type R to type V.


3 Answers

It's little confusing to understand what the explanation means.

To explain it as simple as I can, the method andThen returns a function that first applies a given function to an input and then applies another function to the result of that application.

Assume we had two functions f and g , function f doing some logic and function g doing some other type of logic so when you compose f.andThen(g) that essentially means g(f(x)) i.e. we first apply the function given as argument f(x) and then apply the function g to the result.

Example:

BiFunction<Integer, Integer, Integer> f = Math::addExact; 
Function<Integer, Integer> g = e -> e * 2; 
System.out.println(f.andThen(g).apply(10,10)); // 40

We first call function f(10, 10) and then take the result of that which is 20, pass it to the function g(20) and that is executed multiplying 20 by 2 hence yielding 40.

To be honest the syntax to call a function in Java is not the best it can be so I can understand when someone looks at this the first time it might be difficult to grasp and gets harder to follow the more you compose functions, for example in C# one could simply do g(f(10, 10)) which visibly to the eye is easier to follow, read and understand.

What's the need of this method? How does it actually fit in the picture?

In my experience, it's not common that I've composed functions as shown above but a typical scenario I could imagine is if you have various utility methods that do some logic where the result of one function is further passed to other functions for processing in which case you can then use function composition to create various transformation pipelines by composing the utility methods.

like image 151
Ousmane D. Avatar answered Oct 02 '22 14:10

Ousmane D.


I think the main purpose of the andThen function is to make your code more readable and more functional.

Let's look at and example:

BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
Function<Integer, Integer> negate = x -> -x;
BiFunction<Integer, Integer, Integer> newFunction = add.andThen(negate);

Guess what newFunction does? It adds andThen negates two numbers! See how similar to English this line is:

BiFunction<Integer, Integer, Integer> newFunction = add.andThen(negate);

If you call .apply(1, 2), you know you'd get -3.

Sure, you could do this without using andThen:

BiFunction<Integer, Integer, Integer> newFunction = (x, y) -> negate.apply(add.apply(x, y))

But look how unreadable that is!

Coding functionally can sometimes make things much easier to read and understand.

like image 39
Sweeper Avatar answered Oct 02 '22 12:10

Sweeper


Consider f1.andThen(f2) :

  1. First, f1 will take 2 elements and result in only 1
  2. after that, f2 will take the result of f1 and tranform it to another result
BiFunction<Integer, Integer, Integer> plus10 = (i1, i2) -> i1 + i2 + 10;

Function<Integer, Integer> mult = i -> i * 5;

System.out.println(plus10.andThen(mult).apply(5, 6)); // (5+6+10) *5 = 105

It's a way to reduce computation

int val1 = plus10.apply(5, 6);
int res1 = mult.apply(val1);

int res2 = plus10.andThen(mult).apply(5, 6);
System.out.println(res1 == res2);            //true

It's more and more usefull when you have several function to use, because there is the same method for Function, so you can chain them :

System.out.println(plus10.andThen(mult).andThen(mult).andThen(mult).apply(5, 6)); 
// (5+6+10)*5*5*5 = 2625
like image 32
azro Avatar answered Oct 02 '22 14:10

azro