diff --git a/core-java-modules/core-java-string-algorithms-3/README.md b/core-java-modules/core-java-string-algorithms-3/README.md
new file mode 100644
index 0000000000..3aa31cea53
--- /dev/null
+++ b/core-java-modules/core-java-string-algorithms-3/README.md
@@ -0,0 +1,5 @@
+## Java String Algorithms
+
+This module contains articles about string-related algorithms.
+
+### Relevant Articles:
diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml
new file mode 100644
index 0000000000..a5dd31c762
--- /dev/null
+++ b/core-java-modules/core-java-string-algorithms-3/pom.xml
@@ -0,0 +1,69 @@
+
+ 4.0.0
+ core-java-string-algorithms-3
+ 0.1.0-SNAPSHOT
+ jar
+ core-java-string-algorithms-3
+
+
+ com.baeldung
+ parent-java
+ 0.0.1-SNAPSHOT
+ ../../parent-java
+
+
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+ com.google.guava
+ guava
+ 28.1-jre
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit-jupiter-api.version}
+ test
+
+
+
+
+ core-java-string-algorithms-3
+
+
+ src/main/resources
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+ -parameters
+
+
+
+
+
+
+ 3.8.1
+ 3.6.1
+ 27.0.1-jre
+ 5.3.1
+
+
+
diff --git a/core-java-modules/core-java-string-algorithms-3/src/main/java/com/baeldung/anagram/Anagram.java b/core-java-modules/core-java-string-algorithms-3/src/main/java/com/baeldung/anagram/Anagram.java
new file mode 100644
index 0000000000..360bc5c6de
--- /dev/null
+++ b/core-java-modules/core-java-string-algorithms-3/src/main/java/com/baeldung/anagram/Anagram.java
@@ -0,0 +1,62 @@
+package com.baeldung.anagram;
+
+import java.util.Arrays;
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Multiset;
+
+public class Anagram {
+ // This definition only works for single byte encoding character set.
+ // For multibyte encoding, such as UTF-8, 16, 32 etc.,
+ // we need to increase this number so that it can contain all possible characters.
+ private static int CHARACTER_RANGE = 256;
+
+ public boolean isAnagramSort(String string1, String string2) {
+ if (string1.length() != string2.length()) {
+ return false;
+ }
+ char[] a1 = string1.toCharArray();
+ char[] a2 = string2.toCharArray();
+ Arrays.sort(a1);
+ Arrays.sort(a2);
+ return Arrays.equals(a1, a2);
+ }
+
+ public boolean isAnagramCounting(String string1, String string2) {
+ if (string1.length() != string2.length()) {
+ return false;
+ }
+ int count[] = new int[CHARACTER_RANGE];
+ for (int i = 0; i < string1.length(); i++) {
+ count[string1.charAt(i)]++;
+ count[string2.charAt(i)]--;
+ }
+ for (int i = 0; i < CHARACTER_RANGE; i++) {
+ if (count[i] != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean isAnagramMultiset(String string1, String string2) {
+ if (string1.length() != string2.length()) {
+ return false;
+ }
+ Multiset multiset1 = HashMultiset.create();
+ Multiset multiset2 = HashMultiset.create();
+ for (int i = 0; i < string1.length(); i++) {
+ multiset1.add(string1.charAt(i));
+ multiset2.add(string2.charAt(i));
+ }
+ return multiset1.equals(multiset2);
+ }
+
+ public boolean isLetterBasedAnagramMultiset(String string1, String string2) {
+ return isAnagramMultiset(preprocess(string1), preprocess(string2));
+ }
+
+ private String preprocess(String source) {
+ return source.replaceAll("[^a-zA-Z]", "").toLowerCase();
+ }
+
+}
diff --git a/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/anagram/AnagramUnitTest.java b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/anagram/AnagramUnitTest.java
new file mode 100644
index 0000000000..bedeeb9418
--- /dev/null
+++ b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/anagram/AnagramUnitTest.java
@@ -0,0 +1,72 @@
+package com.baeldung.anagram;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class AnagramUnitTest {
+ @Test
+ public void givenAnagram_whenUsingSort_thenIdentifyAnagram() {
+ Anagram anagram = new Anagram();
+ String string1 = "abcab";
+ String string2 = "cabba";
+ assertTrue(anagram.isAnagramSort(string1, string2));
+ }
+
+ @Test
+ public void givenAnagram_whenUsingCounting_thenIdentifyAnagram() {
+ Anagram anagram = new Anagram();
+ String string1 = "abcab";
+ String string2 = "cabba";
+ assertTrue(anagram.isAnagramCounting(string1, string2));
+ }
+
+ @Test
+ public void givenAnagram_whenUsingMultiset_thenIdentifyAnagram() {
+ Anagram anagram = new Anagram();
+ String string1 = "abcab";
+ String string2 = "cabba";
+ assertTrue(anagram.isAnagramMultiset(string1, string2));
+ }
+
+ @Test
+ public void givenAnagram_whenUsingLetterBasedMultiset_thenIdentifyAnagram() {
+ Anagram anagram = new Anagram();
+ String string1 = "A decimal point";
+ String string2 = "I’m a dot in place.";
+ assertTrue(anagram.isLetterBasedAnagramMultiset(string1, string2));
+ }
+
+ @Test
+ public void givenNonAnagram_whenUsingSort_thenIdentifyNotAnagram() {
+ Anagram anagram = new Anagram();
+ String string1 = "abcaba";
+ String string2 = "cabbac";
+ assertFalse(anagram.isAnagramSort(string1, string2));
+ }
+
+ @Test
+ public void givenNonAnagram_whenUsingCounting_thenIdentifyNotAnagram() {
+ Anagram anagram = new Anagram();
+ String string1 = "abcaba";
+ String string2 = "cabbac";
+ assertFalse(anagram.isAnagramCounting(string1, string2));
+ }
+
+ @Test
+ public void givenNonAnagram_whenUsingMultiset_thenIdentifyNotAnagram() {
+ Anagram anagram = new Anagram();
+ String string1 = "abcaba";
+ String string2 = "cabbac";
+ assertFalse(anagram.isAnagramMultiset(string1, string2));
+ }
+
+ @Test
+ public void ggivenNonAnagram_whenUsingLetterBasedMultiset_thenIdentifyAnagram() {
+ Anagram anagram = new Anagram();
+ String string1 = "A decimal point";
+ String string2 = "I’m dot in place.";
+ assertFalse(anagram.isAnagramMultiset(string1, string2));
+ }
+}