diff --git a/algorithms-modules/algorithms-miscellaneous-4/pom.xml b/algorithms-modules/algorithms-miscellaneous-4/pom.xml
index ed752a6b41..0e0841b72e 100644
--- a/algorithms-modules/algorithms-miscellaneous-4/pom.xml
+++ b/algorithms-modules/algorithms-miscellaneous-4/pom.xml
@@ -13,18 +13,32 @@
1.0.0-SNAPSHOT
-
-
- com.google.guava
- guava
- ${guava.version}
-
-
- org.projectlombok
- lombok
- ${lombok.version}
- provided
-
-
+
+ 3.3.3
+ 4.4
+
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
+
+ com.github.dpaukov
+ combinatoricslib3
+ ${combinatoricslib3.version}
+
+
+ org.apache.commons
+ commons-collections4
+ ${commons-collections4.version}
+
+
\ No newline at end of file
diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/ArrayHelper.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/ArrayHelper.java
new file mode 100644
index 0000000000..6b4f1fcb12
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/ArrayHelper.java
@@ -0,0 +1,14 @@
+package com.baeldung.algorithms.stringpermutation;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ArrayHelper {
+
+ private ArrayHelper() {
+ }
+
+ static List toCharacterList(final String string) {
+ return string.chars().mapToObj(s -> ((char) s)).collect(Collectors.toList());
+ }
+}
diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApache.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApache.java
new file mode 100644
index 0000000000..c2522a6ec5
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApache.java
@@ -0,0 +1,20 @@
+package com.baeldung.algorithms.stringpermutation;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.iterators.PermutationIterator;
+
+public class StringPermutationsApache {
+
+ public Collection> eagerPermutationWithRepetitions(final String string) {
+ final List characters = ArrayHelper.toCharacterList(string);
+ return CollectionUtils.permutations(characters);
+ }
+
+ public PermutationIterator lazyPermutationWithoutRepetitions(final String string) {
+ final List characters = ArrayHelper.toCharacterList(string);
+ return new PermutationIterator<>(characters);
+ }
+
+}
diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLib.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLib.java
new file mode 100644
index 0000000000..78182f8045
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLib.java
@@ -0,0 +1,26 @@
+package com.baeldung.algorithms.stringpermutation;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.paukov.combinatorics3.Generator;
+import org.paukov.combinatorics3.PermutationGenerator.TreatDuplicatesAs;
+
+public class StringPermutationsCombinatoricsLib {
+
+ public List> permutationWithoutRepetitions(final String string) {
+ List chars = ArrayHelper.toCharacterList(string);
+ return Generator.permutation(chars)
+ .simple()
+ .stream()
+ .collect(Collectors.toList());
+ }
+
+ public List> permutationWithRepetitions(final String string) {
+ List chars = ArrayHelper.toCharacterList(string);
+ return Generator.permutation(chars)
+ .simple(TreatDuplicatesAs.IDENTICAL)
+ .stream()
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuava.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuava.java
new file mode 100644
index 0000000000..d055381bf1
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuava.java
@@ -0,0 +1,18 @@
+package com.baeldung.algorithms.stringpermutation;
+
+import com.google.common.collect.Collections2;
+import java.util.Collection;
+import java.util.List;
+
+public class StringPermutationsGuava {
+
+ public Collection> permutationWithRepetitions(final String string) {
+ final List characters = ArrayHelper.toCharacterList(string);
+ return Collections2.permutations(characters);
+ }
+public Collection> permutationWithoutRepetitions(final String string) {
+ final List characters = ArrayHelper.toCharacterList(string);
+ return Collections2.orderedPermutations(characters);
+}
+
+}
diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApacheUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApacheUnitTest.java
new file mode 100644
index 0000000000..d0deb85887
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApacheUnitTest.java
@@ -0,0 +1,43 @@
+package com.baeldung.algorithms.stringpermutation;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.commons.collections4.iterators.PermutationIterator;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+class StringPermutationsApacheUnitTest {
+
+ @CsvSource({"abc, 6",
+ "hello, 120",
+ "aaaaaa, 720"})
+ @DisplayName("Apache permutation for ")
+ void testPermutationsWithRepetitions(String string, int numberOfPermutations) {
+ StringPermutationsApache permutationGenerator = new StringPermutationsApache();
+ final Collection> permutations = permutationGenerator.eagerPermutationWithRepetitions(string);
+ final int size = permutations.size();
+ assertThat(permutations)
+ .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size)
+ .hasSize(numberOfPermutations);
+ }
+
+ @ParameterizedTest
+ @CsvSource({"abc, 6",
+ "hello, 120",
+ "aaaaaa, 720"})
+ void testPermutationsWithoutRepetitions(String string, int numberOfPermutations) {
+ StringPermutationsApache permutationGenerator = new StringPermutationsApache();
+ final PermutationIterator permutations = permutationGenerator.lazyPermutationWithoutRepetitions(string);
+ int size = 0;
+ while (permutations.hasNext()) {
+ permutations.next();
+ ++size;
+ }
+ assertThat(size)
+ .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size)
+ .isEqualTo(numberOfPermutations);
+ }
+}
\ No newline at end of file
diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLibUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLibUnitTest.java
new file mode 100644
index 0000000000..faca3d8f30
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLibUnitTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.algorithms.stringpermutation;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+class StringPermutationsCombinatoricsLibUnitTest {
+
+ @ParameterizedTest
+ @CsvSource({"abc, 6",
+ "hello, 120",
+ "aaaaaa, 720"})
+ void testPermutationsWithRepetitions(String string, int numberOfPermutations) {
+ StringPermutationsCombinatoricsLib permutationGenerator = new StringPermutationsCombinatoricsLib();
+ final List> permutations = permutationGenerator.permutationWithRepetitions(string);
+ final int size = permutations.size();
+ assertThat(permutations)
+ .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size)
+ .hasSize(numberOfPermutations);
+ }
+
+ @ParameterizedTest
+ @CsvSource({"abc, 6",
+ "hello, 60",
+ "aaaaaa, 1"})
+ void testPermutationsWithoutRepetitions(String string, int numberOfPermutations) {
+ StringPermutationsCombinatoricsLib permutationGenerator = new StringPermutationsCombinatoricsLib();
+ final List> permutations = permutationGenerator.permutationWithoutRepetitions(string);
+ final int size = permutations.size();
+ assertThat(permutations)
+ .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size)
+ .hasSize(numberOfPermutations);
+ }
+}
\ No newline at end of file
diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuavaUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuavaUnitTest.java
new file mode 100644
index 0000000000..d2da100997
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuavaUnitTest.java
@@ -0,0 +1,38 @@
+package com.baeldung.algorithms.stringpermutation;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Collection;
+import java.util.List;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+class StringPermutationsGuavaUnitTest {
+
+ @ParameterizedTest
+ @CsvSource({"abc, 6",
+ "hello, 120",
+ "aaaaaa, 720"})
+ void testPermutationsWithRepetitions(String string, int numberOfPermutations) {
+ StringPermutationsGuava permutationGenerator = new StringPermutationsGuava();
+ final Collection> permutations = permutationGenerator.permutationWithRepetitions(string);
+ final int size = permutations.size();
+ assertThat(permutations)
+ .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size)
+ .hasSize(numberOfPermutations);
+ }
+
+ @ParameterizedTest
+ @CsvSource({"abc, 6",
+ "hello, 60",
+ "aaaaaa, 1"})
+ void testPermutationsWithoutRepetitions(String string, int numberOfPermutations) {
+ StringPermutationsGuava permutationGenerator = new StringPermutationsGuava();
+ final Collection> permutations = permutationGenerator.permutationWithoutRepetitions(string);
+ final int size = permutations.size();
+ assertThat(permutations)
+ .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size)
+ .hasSize(numberOfPermutations);
+ }
+
+}
\ No newline at end of file