diff --git a/core-java-modules/core-java-string-operations-7/pom.xml b/core-java-modules/core-java-string-operations-7/pom.xml
index cea3e32f2f..ebc587715d 100644
--- a/core-java-modules/core-java-string-operations-7/pom.xml
+++ b/core-java-modules/core-java-string-operations-7/pom.xml
@@ -39,6 +39,11 @@
icu4j
${icu4j.version}
+
+ org.apache.commons
+ commons-collections4
+ ${apache.commons.collection.version}
+
org.junit.jupiter
junit-jupiter
@@ -75,6 +80,7 @@
11
11
3.13.0
+ 4.4
2.9.1
1.10.0
74.1
diff --git a/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/morse/MorseTranslator.java b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/morse/MorseTranslator.java
new file mode 100644
index 0000000000..8d141f66e1
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/morse/MorseTranslator.java
@@ -0,0 +1,103 @@
+package com.baeldung.morse;
+
+import org.apache.commons.collections4.BidiMap;
+import org.apache.commons.collections4.bidimap.DualHashBidiMap;
+
+public class MorseTranslator {
+
+ private static final BidiMap morseAlphabet = new DualHashBidiMap<>();
+
+ static {
+ morseAlphabet.put("A", ".-");
+ morseAlphabet.put("B", "-...");
+ morseAlphabet.put("C", "-.-.");
+ morseAlphabet.put("D", "-..");
+ morseAlphabet.put("E", ".");
+ morseAlphabet.put("F", "..-.");
+ morseAlphabet.put("G", "--.");
+ morseAlphabet.put("H", "....");
+ morseAlphabet.put("I", "..");
+ morseAlphabet.put("J", ".---");
+ morseAlphabet.put("K", "-.-");
+ morseAlphabet.put("L", ".-..");
+ morseAlphabet.put("M", "--");
+ morseAlphabet.put("N", "-.");
+ morseAlphabet.put("O", "---");
+ morseAlphabet.put("P", ".--.");
+ morseAlphabet.put("Q", "--.-");
+ morseAlphabet.put("R", ".-.");
+ morseAlphabet.put("S", "...");
+ morseAlphabet.put("T", "-");
+ morseAlphabet.put("U", "..-");
+ morseAlphabet.put("V", "...-");
+ morseAlphabet.put("W", ".--");
+ morseAlphabet.put("X", "-..-");
+ morseAlphabet.put("Y", "-.--");
+ morseAlphabet.put("Z", "--..");
+ morseAlphabet.put("0", "-----");
+ morseAlphabet.put("1", ".----");
+ morseAlphabet.put("2", "..---");
+ morseAlphabet.put("3", "...--");
+ morseAlphabet.put("4", "....-");
+ morseAlphabet.put("5", ".....");
+ morseAlphabet.put("6", "-....");
+ morseAlphabet.put("7", "--...");
+ morseAlphabet.put("8", "---..");
+ morseAlphabet.put("9", "----.");
+ morseAlphabet.put(".", ".-.-.-");
+ morseAlphabet.put(",", "--..--");
+ morseAlphabet.put("?", "..--..");
+ morseAlphabet.put("'", ".----.");
+ morseAlphabet.put("!", "-.-.-----.");
+ morseAlphabet.put("/", "-..-.");
+ morseAlphabet.put("(", "-.--.");
+ morseAlphabet.put(")", "-.--.-");
+ morseAlphabet.put("&", ".-...");
+ morseAlphabet.put(":", "---...");
+ morseAlphabet.put(";", "-.-.-.");
+ morseAlphabet.put("=", "-...-");
+ morseAlphabet.put("+", ".-.-.");
+ morseAlphabet.put("-", "-....-");
+ morseAlphabet.put("_", "..--.-");
+ morseAlphabet.put("\"", ".-..-.");
+ morseAlphabet.put("$", "...-..-");
+ morseAlphabet.put("@", ".--.-.");
+ morseAlphabet.put(" ", "/");
+ }
+
+ static String englishToMorse(String english) {
+ if (english == null) {
+ return null;
+ }
+ String upperCaseEnglish = english.toUpperCase();
+ String[] morse = new String[upperCaseEnglish.length()];
+ for (int index = 0; index < upperCaseEnglish.length(); index++) {
+ String morseCharacter = morseAlphabet.get(String.valueOf(upperCaseEnglish.charAt(index)));
+ if (morseCharacter == null) {
+ throw new IllegalArgumentException("Character " + upperCaseEnglish.charAt(index) + " can't be translated to morse");
+ }
+ morse[index] = morseCharacter;
+ }
+ return String.join(" ", morse);
+ }
+
+ static String morseToEnglish(String morse) {
+ if (morse == null) {
+ return null;
+ }
+ if (morse.isEmpty()) {
+ return "";
+ }
+ String[] morseUnitCharacters = morse.split(" ");
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int index = 0; index < morseUnitCharacters.length; index ++) {
+ String englishCharacter = morseAlphabet.getKey(morseUnitCharacters[index]);
+ if (englishCharacter == null) {
+ throw new IllegalArgumentException("Character " + morseUnitCharacters[index] + " is not a valid morse character");
+ }
+ stringBuilder.append(englishCharacter);
+ }
+ return stringBuilder.toString();
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/morse/MorseTranslatorUnitTest.java b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/morse/MorseTranslatorUnitTest.java
new file mode 100644
index 0000000000..f1ab2c961f
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/morse/MorseTranslatorUnitTest.java
@@ -0,0 +1,55 @@
+package com.baeldung.morse;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+public class MorseTranslatorUnitTest {
+
+ @ParameterizedTest
+ @ValueSource(strings = {"MORSE CODE!", "morse code!", "mOrSe cOdE!"})
+ void givenAValidEnglishWordWhateverTheCapitalization_whenEnglishToMorse_thenTranslatedToMorse(String english) {
+ assertEquals("-- --- .-. ... . / -.-. --- -.. . -.-.-----.", MorseTranslator.englishToMorse(english));
+ }
+
+ @Test
+ void givenAnEnglishWordWithAnIllegalCharacter_whenEnglishToMorse_thenThrows() {
+ String english = "~This sentence starts with an illegal character";
+ assertThrows(IllegalArgumentException.class, () -> MorseTranslator.englishToMorse(english));
+ }
+
+ @Test
+ void givenNull_whenEnglishToMorse_thenNull() {
+ assertNull(MorseTranslator.englishToMorse(null));
+ }
+
+ @Test
+ void givenEmptyString_whenEnglishToMorse_thenEmptyArray() {
+ assertEquals("", MorseTranslator.englishToMorse(""));
+ }
+
+ @Test
+ void givenAValidMorseWord_whenMorseToEnglish_thenTranslatedToUpperCaseEnglish() {
+ assertEquals("MORSE CODE!", MorseTranslator.morseToEnglish("-- --- .-. ... . / -.-. --- -.. . -.-.-----."));
+ }
+
+ @Test
+ void givenAMorseWordWithAnIllegalCharacter_whenMorseToEnglish_thenThrows() {
+ assertThrows(IllegalArgumentException.class, () -> MorseTranslator.morseToEnglish(".!!!!!!!"));
+ }
+
+ @Test
+ void givenNull_whenMorseToEnglish_thenNull() {
+ assertNull(MorseTranslator.morseToEnglish(null));
+ }
+
+ @Test
+ void givenEmptyArray_whenMorseToEnglish_thenEmptyString() {
+ assertEquals("", MorseTranslator.morseToEnglish(""));
+ }
+
+}
\ No newline at end of file