diff --git a/.gitignore b/.gitignore
index 48b52bec06..aeb63f7323 100644
--- a/.gitignore
+++ b/.gitignore
@@ -99,4 +99,7 @@ spring-boot-modules/spring-boot-react/frontend/yarn.lock
spring-boot-modules/spring-boot-properties-3/*.log
# SDKMan
-.sdkmanrc
\ No newline at end of file
+.sdkmanrc
+
+# Localstack
+**/.localstack
\ No newline at end of file
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
diff --git a/core-java-modules/core-java-collections-list-4/README.md b/core-java-modules/core-java-collections-list-4/README.md
index 4c020969e3..34b680e7dc 100644
--- a/core-java-modules/core-java-collections-list-4/README.md
+++ b/core-java-modules/core-java-collections-list-4/README.md
@@ -6,4 +6,6 @@ This module contains articles about the Java List collection
- [Working With a List of Lists in Java](https://www.baeldung.com/java-list-of-lists)
- [Reverse an ArrayList in Java](https://www.baeldung.com/java-reverse-arraylist)
- [Sort a List Alphabetically in Java](https://www.baeldung.com/java-sort-list-alphabetically)
+- [Arrays.asList() vs Collections.singletonList()](https://www.baeldung.com/java-aslist-vs-singletonlist)
+- [Replace Element at a Specific Index in a Java ArrayList](https://www.baeldung.com/java-arraylist-replace-at-index)
- [[<-- Prev]](/core-java-modules/core-java-collections-list-3)
diff --git a/core-java-modules/core-java-collections-maps-5/README.md b/core-java-modules/core-java-collections-maps-5/README.md
index 24fb1b56d8..a131c669c6 100644
--- a/core-java-modules/core-java-collections-maps-5/README.md
+++ b/core-java-modules/core-java-collections-maps-5/README.md
@@ -8,4 +8,5 @@
- [Java Map – keySet() vs. entrySet() vs. values() Methods](https://www.baeldung.com/java-map-entries-methods)
- [Java IdentityHashMap Class and Its Use Cases](https://www.baeldung.com/java-identityhashmap)
- [How to Invert a Map in Java](https://www.baeldung.com/java-invert-map)
+- [Implementing a Map with Multiple Keys in Java](https://www.baeldung.com/java-multiple-keys-map)
- More articles: [[<-- prev]](../core-java-collections-maps-4)
diff --git a/core-java-modules/core-java-concurrency-advanced-4/README.md b/core-java-modules/core-java-concurrency-advanced-4/README.md
index d9207644b3..b9881fd475 100644
--- a/core-java-modules/core-java-concurrency-advanced-4/README.md
+++ b/core-java-modules/core-java-concurrency-advanced-4/README.md
@@ -7,3 +7,4 @@
- [Producer-Consumer Problem With Example in Java](https://www.baeldung.com/java-producer-consumer-problem)
- [Acquire a Lock by a Key in Java](https://www.baeldung.com/java-acquire-lock-by-key)
- [Differences Between set() and lazySet() in Java Atomic Variables](https://www.baeldung.com/java-atomic-set-vs-lazyset)
+- [Volatile vs. Atomic Variables in Java](https://www.baeldung.com/java-volatile-vs-atomic)
diff --git a/core-java-modules/core-java-exceptions-4/README.md b/core-java-modules/core-java-exceptions-4/README.md
index 1ea95510e9..ccc40f3858 100644
--- a/core-java-modules/core-java-exceptions-4/README.md
+++ b/core-java-modules/core-java-exceptions-4/README.md
@@ -7,4 +7,5 @@ This module contains articles about core java exceptions
- [Java Missing Return Statement](https://www.baeldung.com/java-missing-return-statement)
- [Convert long to int Type in Java](https://www.baeldung.com/java-convert-long-to-int)
- [“Sneaky Throws” in Java](https://www.baeldung.com/java-sneaky-throws)
-- [[<-- Prev]](../core-java-exceptions-3)
\ No newline at end of file
+- [Get the Current Stack Trace in Java](https://www.baeldung.com/java-get-current-stack-trace)
+- [[<-- Prev]](../core-java-exceptions-3)
diff --git a/core-java-modules/core-java-lang-oop-constructors/README.md b/core-java-modules/core-java-lang-oop-constructors/README.md
index ddd0ec6afb..a552a79721 100644
--- a/core-java-modules/core-java-lang-oop-constructors/README.md
+++ b/core-java-modules/core-java-lang-oop-constructors/README.md
@@ -11,3 +11,4 @@ This module contains article about constructors in Java
- [Constructors in Java Abstract Classes](https://www.baeldung.com/java-abstract-classes-constructors)
- [Java Implicit Super Constructor is Undefined Error](https://www.baeldung.com/java-implicit-super-constructor-is-undefined-error)
- [Constructor Specification in Java](https://www.baeldung.com/java-constructor-specification)
+- [Static vs. Instance Initializer Block in Java](https://www.baeldung.com/java-static-instance-initializer-blocks)
diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java
index 0aba09a539..8fe50efd69 100644
--- a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java
+++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java
@@ -17,9 +17,9 @@ import static org.junit.Assert.assertTrue;
public class FileDownloadIntegrationTest {
- static String FILE_URL = "https://s3.amazonaws.com/baeldung.com/Do+JSON+with+Jackson+by+Baeldung.pdf";
+ static String FILE_URL = "https://s3.amazonaws.com/baeldung.com/Do+JSON+with+Jackson.pdf?__s=vatuzcrazsqopnn7finb";
static String FILE_NAME = "file.dat";
- static String FILE_MD5_HASH = "753197aa27f162faa3e3c2e48ee5eb07";
+ static String FILE_MD5_HASH = "CE20E17B1E1FBF65A85E74AC00FA1FD8";
@Test
public void givenJavaIO_whenDownloadingFile_thenDownloadShouldBeCorrect() throws NoSuchAlgorithmException, IOException {
diff --git a/core-java-modules/core-java-numbers-5/README.md b/core-java-modules/core-java-numbers-5/README.md
index dd80febce9..d7e37d0ee7 100644
--- a/core-java-modules/core-java-numbers-5/README.md
+++ b/core-java-modules/core-java-numbers-5/README.md
@@ -1,2 +1,3 @@
### Relevant Articles:
- [Check if a Number Is Odd or Even](https://www.baeldung.com/java-check-number-parity)
+- [How to Check Whether an Integer Exists in a Range with Java](https://www.baeldung.com/java-interval-contains-integer)
diff --git a/core-java-modules/core-java-streams-4/README.md b/core-java-modules/core-java-streams-4/README.md
index 86b293566a..80e4534b0f 100644
--- a/core-java-modules/core-java-streams-4/README.md
+++ b/core-java-modules/core-java-streams-4/README.md
@@ -2,3 +2,4 @@
- [Count Occurrences Using Java groupingBy Collector](https://www.baeldung.com/java-groupingby-count)
- [How to Split a Stream into Multiple Streams](https://www.baeldung.com/java-split-stream)
+- [Filter Java Stream to 1 and Only 1 Element](https://www.baeldung.com/java-filter-stream-unique-element)
diff --git a/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/inttostring/IntToStringUnitTest.java b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/inttostring/IntToStringUnitTest.java
new file mode 100644
index 0000000000..b865d0933d
--- /dev/null
+++ b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/inttostring/IntToStringUnitTest.java
@@ -0,0 +1,29 @@
+package com.baeldung.chararraytostring;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class IntToStringUnitTest {
+
+ @Test
+ public void whenValidIntIsPassed_thenShouldConvertToString() {
+ assertEquals("11", Integer.toString(11));
+ assertEquals("11", Integer.toString(+11));
+ assertEquals("-11", Integer.toString(-11));
+ }
+
+ @Test
+ public void whenValidIntIsPassed_thenShouldConvertToValidString() {
+ assertEquals("11", String.valueOf(11));
+ assertEquals("11", String.valueOf(+11));
+ assertEquals("-11", String.valueOf(-11));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void whenNullIntegerObjectIsPassed_thenShouldThrowException() {
+ Integer i = null;
+ System.out.println(String.valueOf(i)); // it prints "null"
+ System.out.println(i.toString());
+ }
+}
diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/namedformatting/NamedFormatter.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/namedformatting/NamedFormatter.java
new file mode 100644
index 0000000000..0fd0642f0e
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/namedformatting/NamedFormatter.java
@@ -0,0 +1,31 @@
+package com.baeldung.namedformatting;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class NamedFormatter {
+ private NamedFormatter() {}
+
+ public static String format(String template, Map parameters) {
+ StringBuilder newTemplate = new StringBuilder(template);
+ List