Search code examples
javasortingjava-streamcomparecomparator

Java sort list with streams first by length then alphabetically


I can sort already by the description length, but how can I alphabetically sort two Article if two of them have the same length? (if the description of two articles has the same length, then the sorting should be alphabetical).

   public List<Article> sortAsc() {
    removeNull();
    return articles.stream()
            .sorted(Comparator.comparingInt(a -> a.getDescription().length()))
            .collect(Collectors.toList());
}




public class ComparatorAppController implements Comparator<String> {

/***
 * compare each element
 * @param o1
 * @param o2
 * @return
 */
public int compare(String o1, String o2) {
    // check length in one direction
    if (o1.length() > o2.length()) {
        return 1;
    }
    // check length in the other direction
    else if (o1.length() < o2.length()) {
        return -1;
    }
    // if same alphabetical order
    return o1.compareTo(o2);
}

}

How can I use my Comparator for this situation? Or should I change it to something else?


Solution

  • If you need to sort first by description length and then by description (alphabetical order), then your first comparison is fine but you also need to add a second comparison by description.

    You can stack a second comparison by using the method thenComparing(). It will perform the second comparison only for elements with same length. There is no need to implement a custom Comparator for this scenario.

    public List<Article> sortAsc() {
        removeNull();
        return articles.stream()
                .sorted(Comparator.comparingInt((Article a) -> a.getDescription().length())
                    .thenComparing(Article::getDescription))
                .collect(Collectors.toList());
    }