diff --git a/core-java-modules/core-java-collections-list-4/pom.xml b/core-java-modules/core-java-collections-list-4/pom.xml
index 8c1d3a881e..b546c5af2a 100644
--- a/core-java-modules/core-java-collections-list-4/pom.xml
+++ b/core-java-modules/core-java-collections-list-4/pom.xml
@@ -45,12 +45,24 @@
jmh-generator-annprocess
${jmh-generator.version}
+
+ org.apache.commons
+ commons-lang3
+ ${apache-commons.version}
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
-
3.0.2
8.1.0
1.2.0
+ 3.0
+ 3.22.0
\ No newline at end of file
diff --git a/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/sorting/alphabetical/SortingListUnitTest.java b/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/sorting/alphabetical/SortingListUnitTest.java
new file mode 100644
index 0000000000..12b6c14181
--- /dev/null
+++ b/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/sorting/alphabetical/SortingListUnitTest.java
@@ -0,0 +1,186 @@
+package com.baeldung.list.sorting.alphabetical;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.text.Collator;
+import java.text.Normalizer;
+import java.text.ParseException;
+import java.text.RuleBasedCollator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+import org.junit.jupiter.api.Test;
+
+public class SortingListUnitTest {
+
+ private static List INPUT_NAMES = Arrays.asList("john", "mike", "usmon", "ken", "harry");
+ private static List EXPECTED_NATURAL_ORDER = Arrays.asList("harry", "john", "ken", "mike", "usmon");
+ private static List EXPECTED_REVERSE_ORDER = Arrays.asList("usmon", "mike", "ken", "john", "harry");
+
+ @Test
+ void givenListOfStrings_whenUsingCollections_thenListIsSorted() {
+
+ Collections.sort(INPUT_NAMES);
+
+ assertThat(INPUT_NAMES).isEqualTo(EXPECTED_NATURAL_ORDER);
+ }
+
+ @Test
+ void givenListOfStrings_whenUsingCollections_thenListIsSortedInReverse() {
+ Comparator reverseComparator = (element1, element2) -> element2.compareTo(element1);
+
+ Collections.sort(INPUT_NAMES, reverseComparator);
+
+ assertThat(INPUT_NAMES).isEqualTo(EXPECTED_REVERSE_ORDER);
+ }
+
+ @Test
+ void givenListOfStringsWithUpperAndLowerCaseMixed_whenCustomComparator_thenListIsSortedCorrectly() {
+ List movieNames = Arrays.asList("amazing SpiderMan", "Godzilla", "Sing", "Minions");
+ List naturalSortOrder = Arrays.asList("Godzilla", "Minions", "Sing", "amazing SpiderMan");
+ List comparatorSortOrder = Arrays.asList("amazing SpiderMan", "Godzilla", "Minions", "Sing");
+
+ Collections.sort(movieNames);
+
+ assertThat(movieNames).isEqualTo(naturalSortOrder);
+
+ Collections.sort(movieNames, Comparator.comparing(s -> s.toLowerCase()));
+
+ assertThat(movieNames).isEqualTo(comparatorSortOrder);
+ }
+
+ @Test
+ void givenListOfStringsIncludingSomeWithSpecialCharacter_whenCustomComparator_thenListIsSortedWithSpecialCharacterLast() {
+ List listWithSpecialCharacters = Arrays.asList("@laska", "blah", "jo", "@sk", "foo");
+
+ List sortedNaturalOrder = Arrays.asList("@laska", "@sk", "blah", "foo", "jo");
+ List sortedSpecialCharacterLast = Arrays.asList("blah", "foo", "jo", "@laska", "@sk");
+
+ Collections.sort(listWithSpecialCharacters);
+
+ assertThat(listWithSpecialCharacters).isEqualTo(sortedNaturalOrder);
+
+ Comparator specialSignComparator = Comparator.comparing(s -> s.startsWith("@"));
+ Comparator specialCharacterComparator = specialSignComparator.thenComparing(Comparator.naturalOrder());
+
+ listWithSpecialCharacters.sort(specialCharacterComparator);
+
+ assertThat(listWithSpecialCharacters).isEqualTo(sortedSpecialCharacterLast);
+ }
+
+ @Test
+ void givenListOfStrings_whenUsingStreamsAndSort_thenListIsSorted() {
+ List sortedList = INPUT_NAMES.stream()
+ .sorted()
+ .collect(Collectors.toList());
+
+ assertThat(sortedList).isEqualTo(EXPECTED_NATURAL_ORDER);
+ }
+
+ @Test
+ void givenListOfStrings_whenUsingStreamsWithComparator_thenListIsSortedInReverseOrder() {
+ List sortedList = INPUT_NAMES.stream()
+ .sorted(Comparator.reverseOrder())
+ .collect(Collectors.toList());
+
+ assertThat(sortedList).isEqualTo(EXPECTED_REVERSE_ORDER);
+ }
+
+ @Test
+ void givenListOfStrings_whenUsingTreeSet_thenListIsSorted() {
+ SortedSet sortedSet = new TreeSet<>(INPUT_NAMES);
+ List sortedList = new ArrayList<>(sortedSet);
+
+ assertThat(sortedList).isEqualTo(EXPECTED_NATURAL_ORDER);
+ }
+
+ @Test
+ void givenListOfStrings_whenSortOnList_thenListIsSorted() {
+
+ INPUT_NAMES.sort(Comparator.reverseOrder());
+
+ assertThat(INPUT_NAMES).isEqualTo(EXPECTED_REVERSE_ORDER);
+ }
+
+ @Test
+ void givenListOfStringsWithAccent_whenUseCollatorWithLocaleSet_thenListIsSortedAccordingToLocaleRules() {
+ List accentedStrings = Arrays.asList("único", "árbol", "cosas", "fútbol");
+ List sortedNaturalOrder = Arrays.asList("cosas", "fútbol", "árbol", "único");
+ List sortedLocaleSensitive = Arrays.asList("árbol", "cosas", "fútbol", "único");
+
+ Collections.sort(accentedStrings);
+ assertThat(accentedStrings).isEqualTo(sortedNaturalOrder);
+
+ Collator esCollator = Collator.getInstance(new Locale("es"));
+
+ accentedStrings.sort((s1, s2) -> {
+ return esCollator.compare(s1, s2);
+ });
+
+ assertThat(accentedStrings).isEqualTo(sortedLocaleSensitive);
+ }
+
+ @Test
+ void givenListOfStringsWithAccentedCharacters_whenComparatorWithNormalizer_thenListIsNormalizeAndSorted() {
+ List accentedStrings = Arrays.asList("único", "árbol", "cosas", "fútbol");
+
+ List naturalOrderSorted = Arrays.asList("cosas", "fútbol", "árbol", "único");
+ List stripAccentSorted = Arrays.asList("árbol", "cosas", "fútbol", "único");
+
+ Collections.sort(accentedStrings);
+ assertThat(accentedStrings).isEqualTo(naturalOrderSorted);
+
+ accentedStrings.sort((o1, o2) -> {
+ o1 = Normalizer.normalize(o1, Normalizer.Form.NFD);
+ o2 = Normalizer.normalize(o2, Normalizer.Form.NFD);
+ return o1.compareTo(o2);
+ });
+
+ assertThat(accentedStrings).isEqualTo(stripAccentSorted);
+ }
+
+ @Test
+ void givenListOfStringsWithAccentedCharacters_whenComparatorWithStripAccents_canStripAccentsAndSort() {
+ List accentedStrings = Arrays.asList("único", "árbol", "cosas", "fútbol");
+
+ List naturalOrderSorted = Arrays.asList("cosas", "fútbol", "árbol", "único");
+ List stripAccentSorted = Arrays.asList("árbol", "cosas", "fútbol", "único");
+
+ Collections.sort(accentedStrings);
+
+ assertThat(accentedStrings).isEqualTo(naturalOrderSorted);
+
+ accentedStrings.sort(Comparator.comparing(input -> StringUtils.stripAccents(input)));
+
+ assertThat(accentedStrings).isEqualTo(stripAccentSorted);
+ }
+
+ @Test
+ void givenListofStrings_whenProvidedTheRuleBasedCollator_thenListIsSortedUsingRuleBasedCollator() throws ParseException {
+
+ List movieNames = Arrays.asList("Godzilla", "AmazingSpiderMan", "Smurfs", "Minions");
+
+ List naturalOrderExpected = Arrays.asList("AmazingSpiderMan", "Godzilla", "Minions", "Smurfs");
+
+ List rulesBasedExpected = Arrays.asList("Smurfs", "Minions", "AmazingSpiderMan", "Godzilla");
+
+ Collections.sort(movieNames);
+
+ assertThat(movieNames).isEqualTo(naturalOrderExpected);
+
+ String rule = "< s, S < m, M < a, A < g, G";
+
+ RuleBasedCollator collator = new RuleBasedCollator(rule);
+ movieNames.sort(collator);
+
+ assertThat(movieNames).isEqualTo(rulesBasedExpected);
+ }
+}