**Get started with Spring 5 and Spring Boot 2, through the ***Learn Spring* course:

*Learn Spring*course:

**>> CHECK OUT THE COURSE**

Last modified: October 1, 2022

In this article, we'll define a *TriFunction* *FunctionalInterface* that represents a function that accepts three arguments and computes the result. Later on, we'll also see an example using the built-in *Function3* of the Vavr library.

Since version 8, Java defines the *BiFunction FunctionalInterface*. It represents a function that accepts two arguments and computes its result. To allow function composition, it also provides an *andThen()* method that applies another *Function* to the result of the *BiFunction*.

**Similarly, we'll define our TriFunction interface and give it the andThen() method:**

```
@FunctionalInterface
public interface TriFunction<T, U, V, R> {
R apply(T t, U u, V v);
default <K> TriFunction<T, U, V, K> andThen(Function<? super R, ? extends K> after) {
Objects.requireNonNull(after);
return (T t, U u, V v) -> after.apply(apply(t, u, v));
}
}
```

Let's see how we can use this interface. We'll define a function that takes three *Integers*, multiply the two first operands and then add the last operand:

`static TriFunction<Integer, Integer, Integer, Integer> multiplyThenAdd = (x, y, z) -> x * y + z;`

Let's note that the result of this method will be accurate only if the product of the two first operands is lower than the *Integer* maximum value.

As an example, we can use the *andThen()* method to define a *TriFunction* that:

- first, applies
*multiplyThenAdd()*to the arguments - then, applies a
*Function*that computes the quotient of the Euclidian division of an*Integer*by 10 to the result of the previous step

`static TriFunction<Integer, Integer, Integer, Integer> multiplyThenAddThenDivideByTen = multiplyThenAdd.andThen(x -> x / 10);`

We can now write some quick tests to check that our *TriFunction*s behave as expected:

```
@Test
void whenMultiplyThenAdd_ThenReturnsCorrectResult() {
assertEquals(25, multiplyThenAdd.apply(2, 10, 5));
}
@Test
void whenMultiplyThenAddThenDivideByTen_ThenReturnsCorrectResult() {
assertEquals(2, multiplyThenAddThenDivideByTen.apply(2, 10, 5));
}
```

As a last note, the operands of the *TriFunction* can be of various types. For instance, we can define a *TriFunction* that converts an *Integer* to a *String* or returns another given *String* depending on a *Boolean* condition:

```
static TriFunction<Integer, String, Boolean, String> convertIntegerOrReturnStringDependingOnCondition = (myInt, myStr, myBool) -> {
if (Boolean.TRUE.equals(myBool)) {
return myInt != null ? myInt.toString() : "";
} else {
return myStr;
}
};
```

**The Vavr library already defines a Function3 interface that has the behavior we want. **First, let's add the Vavr dependency to our project:

```
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>0.10.4</version>
</dependency>
```

We can now redefine the *multiplyThenAdd()* and *multiplyThenAddThenDivideByTen() *methods with it:

```
static Function3<Integer, Integer, Integer, Integer> multiplyThenAdd = (x, y, z) -> x * y + z;
static Function3<Integer, Integer, Integer, Integer> multiplyThenAddThenDivideByTen = multiplyThenAdd.andThen(x -> x / 10);
```

Using Vavr can be a good choice if we need to define functions with up to 8 arguments.* Function4*, *Function5, *… *Function8* are indeed already defined in the library.

In this tutorial, we've implemented our own *FunctionalInterface* for a function that accepts 3 arguments. We've also highlighted that the Vavr library contains an implementation of this kind of function.

As always, the code is available over on GitHub.

Login

0 Comments