1. Overview

In this tutorial, we’ll explore different approaches to sorting a string array according to the element’s length.

2. Comparator

When we work on sorting in Java, we often define a Comparator that returns the order between two arguments. The sorting algorithm applies the sort order generated by the Comparator and returns the sorted result.

When defining a Comparator, we implement the following method:

int compare(T o1, T o2);

According to the Java API, this method must return a negative value if o1 is smaller than o2, zero if both are equal or a positive value if o1 is greater than o2.

In our examples in the latter sections, we’ll use this unsorted string array for illustration purposes:

String[] inputArray = new String[] {"am", "today", "too", "I", "busy"};

We expect the following array when inputArray is sorted by the string length:

String[] SORTED = new String[] {"I", "am", "too", "busy", "today"};

3. Comparison by Custom Comparator

The most trivial way is to define a custom string Comparator that compares numerically based on the string length:

public class StringLengthComparator implements Comparator<String> {
    @Override
    public int compare(String s1, String s2) {
        return Integer.compare(s1.length(), s2.length());
    }
}

We’ll call Array.sort() for sorting an array. In our case, we must provide the second argument, our custom comparator. Otherwise, the sorting will be based on the natural ordering:

@Test
void whenSortByCustomComparator_thenArraySorted() {
    StringLengthComparator comparator = new StringLengthComparator();
    Arrays.sort(inputArray, comparator);
    assertThat(inputArray).isEqualTo(SORTED);
}

Depending on our need, we could define an anonymous class instead of a separate class if the Comparator is for one-off usage:

@Test
void whenSortByInnerClassComparator_thenArraySorted() {
    Arrays.sort(inputArray, new Comparator<String>() {
        @Override
        public int compare(String s1, String s2) {
            return Integer.compare(s1.length(), s2.length());
        }
    });
    assertThat(inputArray).isEqualTo(SORTED);
}

4. Comparison by Lambda Expression

Since Java 8 introduced lambda expression, we can simplify the previous approach by supplying the lambda expression rather than using an anonymous class. A lambda is an anonymous function that can be passed around as an object.

With lambda expression, we can pass the comparison function to Array.sort() as the second argument, without explicitly defining any class. This highly improves the readability of the code:

@Test
void whenSortedByLambda_thenArraySorted() {
    Arrays.sort(inputArray, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
    assertThat(inputArray).isEqualTo(SORTED);
}

The example does the same as in the previous section. It’s just much neater when we define it using lambda expression.

5. Comparison by Comparing Function

Java 8 also introduced convenient comparison static functions in the Comparator class.

Comparator.comparingInt() is the one that we can adopt here. This static function accepts a method reference that returns an integer. For the following example, we’ll apply String::length as the method reference that obtains the length of the string:

@Test
void whenSortedByComparingInt_thenArraySorted() {
    Arrays.sort(inputArray, Comparator.comparingInt(String::length));
    assertThat(inputArray).isEqualTo(SORTED);
}

Again, this does the same as the previous one with an even more simplified syntax.

6. Conclusion

In this article, we explored different approaches to sorting. It’s based on supplying to Array.sort() a dedicated Comparator that sorts an array of strings based on their lengths.

The Comparator can be created from a custom Comparator class, a lambda expression, or a comparing function.

As usual, the complete code examples are available over on GitHub.