diff --git a/core-java-modules/core-java-function/pom.xml b/core-java-modules/core-java-function/pom.xml
index c05f9585b2..febd31b55b 100644
--- a/core-java-modules/core-java-function/pom.xml
+++ b/core-java-modules/core-java-function/pom.xml
@@ -1,7 +1,7 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
core-java-function
0.1.0-SNAPSHOT
@@ -32,6 +32,11 @@
${mockito-inline.version}
test
+
+ io.vavr
+ vavr
+ ${vavr.version}
+
@@ -48,6 +53,7 @@
3.8.0
3.22.0
3.12.0
+ 0.10.4
\ No newline at end of file
diff --git a/core-java-modules/core-java-function/src/main/java/com/baeldung/trifunction/TriFunction.java b/core-java-modules/core-java-function/src/main/java/com/baeldung/trifunction/TriFunction.java
new file mode 100644
index 0000000000..fe374a5349
--- /dev/null
+++ b/core-java-modules/core-java-function/src/main/java/com/baeldung/trifunction/TriFunction.java
@@ -0,0 +1,50 @@
+package com.baeldung.trifunction;
+
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Represents a function that accepts three arguments and produces a result.
+ * This is the three-arity specialization of {@link Function}.
+ *
+ *
This is a functional interface
+ * whose functional method is {@link #apply(Object, Object, Object)}.
+ *
+ * @param the type of the first argument to the function
+ * @param the type of the second argument to the function
+ * @param the type of the third argument to the function
+ * @param the type of the result of the function
+ *
+ * @see Function
+ */
+@FunctionalInterface
+public interface TriFunction {
+
+ /**
+ * Applies this function to the given arguments.
+ *
+ * @param t the first function argument
+ * @param u the second function argument
+ * @param v the third function argument
+ * @return the function result
+ */
+ R apply(T t, U u, V v);
+
+ /**
+ * Returns a composed function that first applies this function to
+ * its input, and then applies the {@code after} function to the result.
+ * If evaluation of either function throws an exception, it is relayed to
+ * the caller of the composed function.
+ *
+ * @param the type of output of the {@code after} function, and of the
+ * composed function
+ * @param after the function to apply after this function is applied
+ * @return a composed function that first applies this function and then
+ * applies the {@code after} function
+ * @throws NullPointerException if after is null
+ */
+ default TriFunction andThen(Function super R, ? extends K> after) {
+ Objects.requireNonNull(after);
+ return (T t, U u, V v) -> after.apply(apply(t, u, v));
+ }
+}
diff --git a/core-java-modules/core-java-function/src/main/java/com/baeldung/trifunction/TriFunctionExample.java b/core-java-modules/core-java-function/src/main/java/com/baeldung/trifunction/TriFunctionExample.java
new file mode 100644
index 0000000000..587da8e28f
--- /dev/null
+++ b/core-java-modules/core-java-function/src/main/java/com/baeldung/trifunction/TriFunctionExample.java
@@ -0,0 +1,17 @@
+package com.baeldung.trifunction;
+
+public class TriFunctionExample {
+
+ public static TriFunction multiplyThenAdd = (x, y, z) -> x * y + z;
+
+ public static TriFunction multiplyThenAddThenDivideByTen = multiplyThenAdd.andThen(x -> x / 10);
+
+ public static TriFunction convertIntegerOrReturnStringDependingOnCondition = (myInt, myStr, myBool) -> {
+ if (Boolean.TRUE.equals(myBool)) {
+ return myInt != null ? myInt.toString() : "";
+ } else {
+ return myStr;
+ }
+ };
+
+}
diff --git a/core-java-modules/core-java-function/src/main/java/com/baeldung/trifunction/VavrFunction3Example.java b/core-java-modules/core-java-function/src/main/java/com/baeldung/trifunction/VavrFunction3Example.java
new file mode 100644
index 0000000000..0747806e74
--- /dev/null
+++ b/core-java-modules/core-java-function/src/main/java/com/baeldung/trifunction/VavrFunction3Example.java
@@ -0,0 +1,11 @@
+package com.baeldung.trifunction;
+
+import io.vavr.Function3;
+
+public class VavrFunction3Example {
+
+ public static Function3 multiplyThenAdd = (x, y, z) -> x * y + z;
+
+ public static Function3 multiplyThenAddThenDivideByTen = multiplyThenAdd.andThen(x -> x / 10);
+
+}
diff --git a/core-java-modules/core-java-function/src/test/java/com/baeldung/trifunction/TriFunctionExampleUnitTest.java b/core-java-modules/core-java-function/src/test/java/com/baeldung/trifunction/TriFunctionExampleUnitTest.java
new file mode 100644
index 0000000000..bb741cee5e
--- /dev/null
+++ b/core-java-modules/core-java-function/src/test/java/com/baeldung/trifunction/TriFunctionExampleUnitTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.trifunction;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+class TriFunctionExampleUnitTest {
+
+ private static final String BAELDUNG = "baeldung";
+
+ @Test
+ void whenMultiplyThenAdd_ThenReturnsCorrectResult() {
+ assertEquals(25, TriFunctionExample.multiplyThenAdd.apply(2, 10, 5));
+ }
+
+ @Test
+ void whenMultiplyThenAddThenDivideByTen_ThenReturnsCorrectResult() {
+ assertEquals(2, TriFunctionExample.multiplyThenAddThenDivideByTen.apply(2, 10, 5));
+ }
+
+ @Test
+ void givenTrueBooleanAndNullInteger_WhenConvertIntegerOrReturnStringDependingOnCondition_ThenEmptyString() {
+ assertEquals("", TriFunctionExample.convertIntegerOrReturnStringDependingOnCondition.apply(null, BAELDUNG, true));
+ }
+
+ @Test
+ void givenTrueBooleanAndNonNullInteger_WhenConvertIntegerOrReturnStringDependingOnCondition_ThenConvertIntegerToString() {
+ assertEquals("88", TriFunctionExample.convertIntegerOrReturnStringDependingOnCondition.apply(88, BAELDUNG, true));
+ }
+
+ @Test
+ void givenFalseBoolean_WhenConvertIntegerOrReturnStringDependingOnCondition_ThenReturnTheString() {
+ assertEquals(BAELDUNG, TriFunctionExample.convertIntegerOrReturnStringDependingOnCondition.apply(null, BAELDUNG, false));
+ }
+
+ @Test
+ void givenNullBoolean_WhenConvertIntegerOrReturnStringDependingOnCondition_ThenReturnTheString() {
+ assertEquals(BAELDUNG, TriFunctionExample.convertIntegerOrReturnStringDependingOnCondition.apply(null, BAELDUNG, null));
+ }
+
+}
diff --git a/core-java-modules/core-java-function/src/test/java/com/baeldung/trifunction/VavrFunction3ExampleUnitTest.java b/core-java-modules/core-java-function/src/test/java/com/baeldung/trifunction/VavrFunction3ExampleUnitTest.java
new file mode 100644
index 0000000000..4571c3a1c5
--- /dev/null
+++ b/core-java-modules/core-java-function/src/test/java/com/baeldung/trifunction/VavrFunction3ExampleUnitTest.java
@@ -0,0 +1,19 @@
+package com.baeldung.trifunction;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class VavrFunction3ExampleUnitTest {
+
+ @Test
+ void whenMultiplyThenAdd_ThenReturnsCorrectResult() {
+ assertEquals(25, VavrFunction3Example.multiplyThenAdd.apply(2, 10, 5));
+ }
+
+ @Test
+ void whenMultiplyThenAddThenDivideByTen_ThenReturnsCorrectResult() {
+ assertEquals(2, VavrFunction3Example.multiplyThenAddThenDivideByTen.apply(2, 10, 5));
+ }
+
+}