diff --git a/algorithms-miscellaneous-1/pom.xml b/algorithms-miscellaneous-1/pom.xml
index 75b031282b..5006670dd9 100644
--- a/algorithms-miscellaneous-1/pom.xml
+++ b/algorithms-miscellaneous-1/pom.xml
@@ -17,6 +17,11 @@
commons-math3
${commons-math3.version}
+
+ com.google.guava
+ guava
+ ${guava.version}
+
commons-codec
commons-codec
@@ -73,6 +78,7 @@
3.6.1
3.9.0
1.11
+ 25.1-jre
\ No newline at end of file
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/factorial/Factorial.java b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/factorial/Factorial.java
new file mode 100644
index 0000000000..43d2221773
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/factorial/Factorial.java
@@ -0,0 +1,63 @@
+package com.baeldung.algorithms.factorial;
+
+import java.math.BigInteger;
+import java.util.stream.LongStream;
+
+import org.apache.commons.math3.util.CombinatoricsUtils;
+
+import com.google.common.math.BigIntegerMath;
+
+public class Factorial {
+
+ public long factorialUsingForLoop(int n) {
+ long fact = 1;
+ for (int i = 2; i <= n; i++) {
+ fact = fact * i;
+ }
+ return fact;
+ }
+
+ public long factorialUsingStreams(int n) {
+ return LongStream.rangeClosed(1, n)
+ .reduce(1, (long x, long y) -> x * y);
+ }
+
+ public long factorialUsingRecursion(int n) {
+ if (n <= 2) {
+ return n;
+ }
+ return n * factorialUsingRecursion(n - 1);
+ }
+
+ private Long[] factorials = new Long[20];
+
+ public long factorialUsingMemoize(int n) {
+
+ if (factorials[n] != null) {
+ return factorials[n];
+ }
+
+ if (n <= 2) {
+ return n;
+ }
+ long nthValue = n * factorialUsingMemoize(n - 1);
+ factorials[n] = nthValue;
+ return nthValue;
+ }
+
+ public BigInteger factorialHavingLargeResult(int n) {
+ BigInteger result = BigInteger.ONE;
+ for (int i = 2; i <= n; i++)
+ result = result.multiply(BigInteger.valueOf(i));
+ return result;
+ }
+
+ public long factorialUsingApacheCommons(int n) {
+ return CombinatoricsUtils.factorial(n);
+ }
+
+ public BigInteger factorialUsingGuava(int n) {
+ return BigIntegerMath.factorial(n);
+ }
+
+}
diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/factorial/FactorialUnitTest.java b/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/factorial/FactorialUnitTest.java
new file mode 100644
index 0000000000..c185dba62b
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/factorial/FactorialUnitTest.java
@@ -0,0 +1,72 @@
+package com.baeldung.algorithms.factorial;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.math.BigInteger;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class FactorialUnitTest {
+
+ Factorial factorial;
+
+ @Before
+ public void setup() {
+ factorial = new Factorial();
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingForLoop_thenCorrect() {
+ int n = 5;
+
+ assertThat(factorial.factorialUsingForLoop(n)).isEqualTo(120);
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingStreams_thenCorrect() {
+ int n = 5;
+
+ assertThat(factorial.factorialUsingStreams(n)).isEqualTo(120);
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingRecursion_thenCorrect() {
+ int n = 5;
+
+ assertThat(factorial.factorialUsingRecursion(n)).isEqualTo(120);
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingMemoize_thenCorrect() {
+ int n = 5;
+
+ assertThat(factorial.factorialUsingMemoize(n)).isEqualTo(120);
+
+ n = 6;
+
+ assertThat(factorial.factorialUsingMemoize(n)).isEqualTo(720);
+ }
+
+ @Test
+ public void whenCalculatingFactorialHavingLargeResult_thenCorrect() {
+ int n = 22;
+
+ assertThat(factorial.factorialHavingLargeResult(n)).isEqualTo(new BigInteger("1124000727777607680000"));
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingApacheCommons_thenCorrect() {
+ int n = 5;
+
+ assertThat(factorial.factorialUsingApacheCommons(n)).isEqualTo(120);
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingGuava_thenCorrect() {
+ int n = 22;
+
+ assertThat(factorial.factorialUsingGuava(n)).isEqualTo(new BigInteger("1124000727777607680000"));
+ }
+
+}