diff --git a/core-java-modules/core-java-functional/README.md b/core-java-modules/core-java-functional/README.md
new file mode 100644
index 0000000000..ff12555376
--- /dev/null
+++ b/core-java-modules/core-java-functional/README.md
@@ -0,0 +1 @@
+## Relevant articles:
diff --git a/core-java-modules/core-java-functional/pom.xml b/core-java-modules/core-java-functional/pom.xml
new file mode 100644
index 0000000000..f00600c794
--- /dev/null
+++ b/core-java-modules/core-java-functional/pom.xml
@@ -0,0 +1,18 @@
+
+
+ 4.0.0
+ core-java-functional
+ 0.1.0-SNAPSHOT
+ core-java-functional
+ jar
+
+ com.baeldung.core-java-modules
+ core-java-modules
+ 0.0.1-SNAPSHOT
+ ../
+
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Currying.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Currying.java
new file mode 100644
index 0000000000..594fea4b8c
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Currying.java
@@ -0,0 +1,26 @@
+package com.baeldung.functional;
+
+import java.util.function.Function;
+
+public class Currying {
+
+ private static Function> weight = mass -> gravity -> mass * gravity;
+
+ private static Function weightOnEarth = weight.apply(9.81);
+
+ private static Function weightOnMars = weight.apply(3.75);
+
+ public static Double weightOnEarth(Double mass) {
+ return weightOnEarth.apply(mass);
+ }
+
+ public static Double weightOnMars(Double mass) {
+ return weightOnMars.apply(mass);
+ }
+
+ public static Function weightOnEarth() {
+ final double gravity = 9.81;
+ return mass -> mass * gravity;
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FirstClassFunctions.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FirstClassFunctions.java
new file mode 100644
index 0000000000..13b408ab27
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FirstClassFunctions.java
@@ -0,0 +1,24 @@
+package com.baeldung.functional;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class FirstClassFunctions {
+
+ public static List sortWithoutLambda(List numbers) {
+ Collections.sort(numbers, new Comparator() {
+ @Override
+ public int compare(Integer n1, Integer n2) {
+ return n1.compareTo(n2);
+ }
+ });
+ return numbers;
+ }
+
+ public static List sortWithLambda(List numbers) {
+ Collections.sort(numbers, (n1, n2) -> n1.compareTo(n2));
+ return numbers;
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FunctionComposition.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FunctionComposition.java
new file mode 100644
index 0000000000..57103be98a
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/FunctionComposition.java
@@ -0,0 +1,20 @@
+package com.baeldung.functional;
+
+import java.util.function.Function;
+
+public class FunctionComposition {
+
+ private static Function log = (value) -> Math.log(value);
+ private static Function sqrt = (value) -> Math.sqrt(value);
+
+ public static Double logThenSqrt(Double number) {
+ Function logThenSqrt = sqrt.compose(log);
+ return (logThenSqrt.apply(3.14));
+ }
+
+ public static Double sqrtThenLog(Double number) {
+ Function sqrtThenLog = sqrt.andThen(log);
+ return (sqrtThenLog.apply(3.14));
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ImmutableData.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ImmutableData.java
new file mode 100644
index 0000000000..738680f743
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ImmutableData.java
@@ -0,0 +1,36 @@
+package com.baeldung.functional;
+
+public class ImmutableData {
+
+ private final String someData;
+
+ private final AnotherImmutableData anotherImmutableData;
+
+ public ImmutableData(final String someData, final AnotherImmutableData anotherImmutableData) {
+ this.someData = someData;
+ this.anotherImmutableData = anotherImmutableData;
+ }
+
+ public String getSomeData() {
+ return someData;
+ }
+
+ public AnotherImmutableData getAnotherImmutableData() {
+ return anotherImmutableData;
+ }
+
+ public class AnotherImmutableData {
+
+ private final Integer someOtherData;
+
+ public AnotherImmutableData(final Integer someData) {
+ this.someOtherData = someData;
+ }
+
+ public Integer getSomeOtherData() {
+ return someOtherData;
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Monads.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Monads.java
new file mode 100644
index 0000000000..c1223c73c7
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Monads.java
@@ -0,0 +1,11 @@
+package com.baeldung.functional;
+
+import java.util.Optional;
+
+public class Monads {
+
+ public static Optional add(Optional val1, Optional val2) {
+ return val1.flatMap(first -> val2.flatMap(second -> Optional.of(first + second)));
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/PureFunctions.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/PureFunctions.java
new file mode 100644
index 0000000000..522b9de9eb
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/PureFunctions.java
@@ -0,0 +1,13 @@
+package com.baeldung.functional;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PureFunctions {
+
+ public static Integer sum(List numbers) {
+ return numbers.stream()
+ .collect(Collectors.summingInt(Integer::intValue));
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Recursion.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Recursion.java
new file mode 100644
index 0000000000..d5492df69d
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/Recursion.java
@@ -0,0 +1,17 @@
+package com.baeldung.functional;
+
+public class Recursion {
+
+ public static Integer headRecursion(Integer number) {
+
+ return (number == 1) ? 1 : number * headRecursion(number - 1);
+
+ }
+
+ public static Integer tailRecursion(Integer number, Integer result) {
+
+ return (number == 1) ? result : tailRecursion(number - 1, result * number);
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ReferentialTransparency.java b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ReferentialTransparency.java
new file mode 100644
index 0000000000..1392cdd00a
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/main/java/com/baeldung/functional/ReferentialTransparency.java
@@ -0,0 +1,39 @@
+package com.baeldung.functional;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class ReferentialTransparency {
+
+ private static Logger logger = Logger.getGlobal();
+
+ public void main() {
+
+ String data = new SimpleData().setData("Baeldung")
+ .getData();
+ logger.log(Level.INFO, new SimpleData().setData("Baeldung")
+ .getData());
+ logger.log(Level.INFO, data);
+ logger.log(Level.INFO, "Baeldung");
+ }
+
+ public class SimpleData {
+
+ private Logger logger = Logger.getGlobal();
+
+ private String data;
+
+ public String getData() {
+ logger.log(Level.INFO, "Get data called for SimpleData");
+ return data;
+ }
+
+ public SimpleData setData(String data) {
+ logger.log(Level.INFO, "Set data called for SimpleData");
+ this.data = data;
+ return this;
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/CurryingUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/CurryingUnitTest.java
new file mode 100644
index 0000000000..0cf96ed566
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/CurryingUnitTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.Test;
+
+public class CurryingUnitTest {
+
+ @Test
+ public void testWeightOnEarth() {
+
+ assertEquals(588.6, Currying.weightOnEarth(60.0), 0.1);
+
+ }
+
+ @Test
+ public void testWeightOnMars() {
+
+ assertEquals(225.0, Currying.weightOnMars(60.0), 0.1);
+
+ }
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FirstClassFunctionsUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FirstClassFunctionsUnitTest.java
new file mode 100644
index 0000000000..8056b44f21
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FirstClassFunctionsUnitTest.java
@@ -0,0 +1,27 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public class FirstClassFunctionsUnitTest {
+
+ @Test
+ public void testSortingWithoutLambda() {
+
+ assertEquals(new Integer(8), FirstClassFunctions.sortWithoutLambda(Arrays.asList(new Integer(10), new Integer(8)))
+ .get(0));
+
+ }
+
+ @Test
+ public void testSortingWithLambda() {
+
+ assertEquals(new Integer(8), FirstClassFunctions.sortWithLambda(Arrays.asList(new Integer(10), new Integer(8)))
+ .get(0));
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FunctionCompositionUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FunctionCompositionUnitTest.java
new file mode 100644
index 0000000000..48d8fb695c
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/FunctionCompositionUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.Test;
+
+public class FunctionCompositionUnitTest {
+
+ @Test
+ public void testLogThenSqrt() {
+
+ assertEquals(1.07, FunctionComposition.logThenSqrt(3.14), 0.01);
+
+ }
+
+ @Test
+ public void testSqrtThenLog() {
+
+ assertEquals(0.57, FunctionComposition.sqrtThenLog(3.14), 0.01);
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/MonadsUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/MonadsUnitTest.java
new file mode 100644
index 0000000000..8258eef59e
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/MonadsUnitTest.java
@@ -0,0 +1,19 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Optional;
+
+import org.junit.Test;
+
+public class MonadsUnitTest {
+
+ @Test
+ public void testOptionalAdd() {
+
+ assertEquals(5, Monads.add(Optional.of(new Integer(2)), Optional.of(new Integer(3)))
+ .get());
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/PureFunctionsUnitTets.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/PureFunctionsUnitTets.java
new file mode 100644
index 0000000000..23cca8bf8d
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/PureFunctionsUnitTets.java
@@ -0,0 +1,18 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public class PureFunctionsUnitTets {
+
+ @Test
+ public void testSortingWithoutLambda() {
+
+ assertEquals(new Integer(18), PureFunctions.sum(Arrays.asList(new Integer(10), new Integer(8))));
+
+ }
+
+}
diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/RecursionUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/RecursionUnitTest.java
new file mode 100644
index 0000000000..aa406dc7ab
--- /dev/null
+++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/functional/RecursionUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.functional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.Test;
+
+public class RecursionUnitTest {
+
+ @Test
+ public void testHeadRecursion() {
+
+ assertEquals(120, Recursion.headRecursion(5));
+
+ }
+
+ @Test
+ public void testTailRecursion() {
+
+ assertEquals(120, Recursion.tailRecursion(5, 1));
+
+ }
+
+}
diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml
index a6aecef741..b995092782 100644
--- a/core-java-modules/pom.xml
+++ b/core-java-modules/pom.xml
@@ -60,6 +60,7 @@
core-java-exceptions-2
core-java-exceptions-3
core-java-function
+ core-java-functional
core-java-io
core-java-io-2