From 316cd48b48fdbc129e47db0d55a89f1a07d24a19 Mon Sep 17 00:00:00 2001 From: alemoles Date: Mon, 5 Dec 2022 04:02:24 -0300 Subject: [PATCH] BAEL-5960 - Functors in Java (#13125) --- .../functional/functors/EnumFunctor.java | 23 +++++++++ .../baeldung/functional/functors/Functor.java | 23 +++++++++ .../functional/functors/FunctorsUnitTest.java | 50 +++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/functors/EnumFunctor.java create mode 100644 core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/functors/Functor.java create mode 100644 core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/functors/FunctorsUnitTest.java diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/functors/EnumFunctor.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/functors/EnumFunctor.java new file mode 100644 index 0000000000..380ebf6708 --- /dev/null +++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/functors/EnumFunctor.java @@ -0,0 +1,23 @@ +package com.baeldung.functional.functors; + +public enum EnumFunctor { + PLUS { + public int apply(int a, int b) { + return a + b; + } + }, MINUS { + public int apply(int a, int b) { + return a - b; + } + }, MULTIPLY { + public int apply(int a, int b) { + return a * b; + } + }, DIVIDE { + public int apply(int a, int b) { + return a / b; + } + }; + + public abstract int apply(int a, int b); +} \ No newline at end of file diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/functors/Functor.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/functors/Functor.java new file mode 100644 index 0000000000..778d0aacb7 --- /dev/null +++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/functors/Functor.java @@ -0,0 +1,23 @@ +package com.baeldung.functional.functors; + +import java.util.function.Function; + +public class Functor { + private final T value; + + public Functor(T value) { + this.value = value; + } + + public Functor map(Function mapper) { + return new Functor<>(mapper.apply(value)); + } + + boolean eq(T other) { + return value.equals(other); + } + + public T getValue() { + return value; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/functors/FunctorsUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/functors/FunctorsUnitTest.java new file mode 100644 index 0000000000..c29851d9c3 --- /dev/null +++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/functors/FunctorsUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.functional.functors; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.function.Function; + +import org.junit.jupiter.api.Test; + +class FunctorsUnitTest { + @Test + public void whenProvideAValue_ShouldMapTheValue() { + Functor functor = new Functor<>(5); + Function addThree = (num) -> num + 3; + Functor mappedFunctor = functor.map(addThree); + assertEquals(8, mappedFunctor.getValue()); + } + + @Test + public void whenApplyAnIdentityToAFunctor_thenResultIsEqualsToInitialValue() { + String value = "baeldung"; + //Identity + Functor identity = new Functor<>(value).map(Function.identity()); + assertTrue(identity.eq(value)); + } + + @Test + public void whenApplyAFunctionToOtherFunction_thenResultIsEqualsBetweenBoth() { + int value = 100; + long expected = 100; + // Composition/Associativity + Function f = Object::toString; + Function g = Long::valueOf; + + Functor left = new Functor<>(value).map(f) + .map(g); + Functor right = new Functor<>(value).map(f.andThen(g)); + + assertTrue(left.eq(expected)); + assertTrue(right.eq(expected)); + } + + @Test + public void whenApplyOperationsToEnumFunctors_thenGetTheProperResult() { + assertEquals(15, EnumFunctor.PLUS.apply(10, 5)); + assertEquals(5, EnumFunctor.MINUS.apply(10, 5)); + assertEquals(50, EnumFunctor.MULTIPLY.apply(10, 5)); + assertEquals(2, EnumFunctor.DIVIDE.apply(10, 5)); + } +} \ No newline at end of file