diff --git a/core-java/pom.xml b/core-java/pom.xml
index a823d836e8..cce714451e 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -203,6 +203,11 @@
mail
1.5.0-b01
+
+ com.ibm.icu
+ icu4j
+ ${icu4j.version}
+
@@ -473,6 +478,7 @@
3.0.0-M1
1.6.0
1.5.0-b01
+ 61.1
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/string/TitleCaseConverter.java b/core-java/src/main/java/com/baeldung/string/TitleCaseConverter.java
new file mode 100644
index 0000000000..0fdda86f2a
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/string/TitleCaseConverter.java
@@ -0,0 +1,68 @@
+package com.baeldung.string;
+
+import com.ibm.icu.lang.UCharacter;
+import com.ibm.icu.text.BreakIterator;
+import org.apache.commons.lang.WordUtils;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+public class TitleCaseConverter {
+
+ private static final String WORD_SEPARATOR = " ";
+
+ public static String convertToTitleCaseIteratingChars(String text) {
+ if (text == null || text.isEmpty()) {
+ return text;
+ }
+
+ StringBuilder converted = new StringBuilder();
+
+ boolean convertNext = true;
+ for (char ch : text.toCharArray()) {
+ if (Character.isSpaceChar(ch)) {
+ convertNext = true;
+ } else if (convertNext) {
+ ch = Character.toTitleCase(ch);
+ convertNext = false;
+ } else {
+ ch = Character.toLowerCase(ch);
+ }
+ converted.append(ch);
+ }
+
+ return converted.toString();
+ }
+
+ public static String convertToTitleCaseSplitting(String text) {
+ if (text == null || text.isEmpty()) {
+ return text;
+ }
+
+ return Arrays
+ .stream(text.split(WORD_SEPARATOR))
+ .map(word -> word.isEmpty()
+ ? word
+ : Character.toTitleCase(word.charAt(0)) + word
+ .substring(1)
+ .toLowerCase())
+ .collect(Collectors.joining(WORD_SEPARATOR));
+ }
+
+ public static String convertToTitleCaseIcu4j(String text) {
+ if (text == null || text.isEmpty()) {
+ return text;
+ }
+
+ return UCharacter.toTitleCase(text, BreakIterator.getTitleInstance());
+ }
+
+ public static String convertToTileCaseWordUtilsFull(String text) {
+ return WordUtils.capitalizeFully(text);
+ }
+
+ public static String convertToTileCaseWordUtils(String text) {
+ return WordUtils.capitalize(text);
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/string/TitleCaseConverterUnitTest.java b/core-java/src/test/java/com/baeldung/string/TitleCaseConverterUnitTest.java
new file mode 100644
index 0000000000..2272565cd3
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/string/TitleCaseConverterUnitTest.java
@@ -0,0 +1,70 @@
+package com.baeldung.string;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TitleCaseConverterUnitTest {
+
+ private static final String TEXT = "tHis IS a tiTLe";
+ private static final String TEXT_EXPECTED = "This Is A Title";
+ private static final String TEXT_EXPECTED_NOT_FULL = "THis IS A TiTLe";
+
+ private static final String TEXT_OTHER_DELIMITERS = "tHis, IS a tiTLe";
+ private static final String TEXT_EXPECTED_OTHER_DELIMITERS = "This, Is A Title";
+ private static final String TEXT_EXPECTED_OTHER_DELIMITERS_NOT_FULL = "THis, IS A TiTLe";
+
+ @Test
+ public void whenConvertingToTitleCaseIterating_thenStringConverted() {
+ assertEquals(TEXT_EXPECTED, TitleCaseConverter.convertToTitleCaseIteratingChars(TEXT));
+ }
+
+ @Test
+ public void whenConvertingToTitleCaseSplitting_thenStringConverted() {
+ assertEquals(TEXT_EXPECTED, TitleCaseConverter.convertToTitleCaseSplitting(TEXT));
+ }
+
+ @Test
+ public void whenConvertingToTitleCaseUsingWordUtilsFull_thenStringConverted() {
+ assertEquals(TEXT_EXPECTED, TitleCaseConverter.convertToTileCaseWordUtilsFull(TEXT));
+ }
+
+ @Test
+ public void whenConvertingToTitleCaseUsingWordUtils_thenStringConvertedOnlyFirstCharacter() {
+ assertEquals(TEXT_EXPECTED_NOT_FULL, TitleCaseConverter.convertToTileCaseWordUtils(TEXT));
+ }
+
+ @Test
+ public void whenConvertingToTitleCaseUsingIcu4j_thenStringConverted() {
+ assertEquals(TEXT_EXPECTED, TitleCaseConverter.convertToTitleCaseIcu4j(TEXT));
+ }
+
+ @Test
+ public void whenConvertingToTitleCaseWithDifferentDelimiters_thenDelimitersKept() {
+ assertEquals(TEXT_EXPECTED_OTHER_DELIMITERS, TitleCaseConverter.convertToTitleCaseIteratingChars(TEXT_OTHER_DELIMITERS));
+ assertEquals(TEXT_EXPECTED_OTHER_DELIMITERS, TitleCaseConverter.convertToTitleCaseSplitting(TEXT_OTHER_DELIMITERS));
+ assertEquals(TEXT_EXPECTED_OTHER_DELIMITERS, TitleCaseConverter.convertToTileCaseWordUtilsFull(TEXT_OTHER_DELIMITERS));
+ assertEquals(TEXT_EXPECTED_OTHER_DELIMITERS_NOT_FULL, TitleCaseConverter.convertToTileCaseWordUtils(TEXT_OTHER_DELIMITERS));
+ assertEquals(TEXT_EXPECTED_OTHER_DELIMITERS, TitleCaseConverter.convertToTitleCaseIcu4j(TEXT_OTHER_DELIMITERS));
+ }
+
+ @Test
+ public void givenNull_whenConvertingToTileCase_thenReturnNull() {
+ assertEquals(null, TitleCaseConverter.convertToTitleCaseIteratingChars(null));
+ assertEquals(null, TitleCaseConverter.convertToTitleCaseSplitting(null));
+ assertEquals(null, TitleCaseConverter.convertToTileCaseWordUtilsFull(null));
+ assertEquals(null, TitleCaseConverter.convertToTileCaseWordUtils(null));
+ assertEquals(null, TitleCaseConverter.convertToTitleCaseIcu4j(null));
+ }
+
+ @Test
+ public void givenEmptyString_whenConvertingToTileCase_thenReturnEmptyString() {
+ assertEquals("", TitleCaseConverter.convertToTitleCaseIteratingChars(""));
+ assertEquals("", TitleCaseConverter.convertToTitleCaseSplitting(""));
+ assertEquals("", TitleCaseConverter.convertToTileCaseWordUtilsFull(""));
+ assertEquals("", TitleCaseConverter.convertToTileCaseWordUtils(""));
+ assertEquals("", TitleCaseConverter.convertToTitleCaseIcu4j(""));
+ }
+
+}