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); + } +}