Wednesday, October 4, 2023

6 ways to sort ArrayList in Java 8? List.sort() + Collections.sort() Example Tutorial

There are many ways to sort an ArrayList in Java 8; for example. you can use the old but still rocking way to sort a List by using Collections.sort() method, or you can use the newly added sort() method in the List interface in Java, or you can use the new java.util.stream API to sort a list of objects. You now have multiple choices when it comes to sort a List or Array in Java. Though, my preferred way is Collections.sort() method because it is available to all the Java versions and its easy to use and it also allows you to sort in any custom order.  The method is overloaded which gives you ability to sort a list of objects into their natural order as well allow you to supply a Comparator of your choice to sort elements into customer order. 

For example, if you a List of Items then you can either sort them based upon their Id or name, which is natural order, or you can sort them based upon their price or delivery date, which is custom order in general. 

Only thing you need to remember is that for natural order sorting, you don't need to provide any Comparator because comparison logic resides in the class itself, in form of compareTo() method, but for custom order sorting, you need to provide a Comparator, which encapsulate the comparison logic required for sorting. 

Java 8 made sorting a list or array of objects easier by not only providing a List.sort() method but also adding several utility methods on java.util.Comparator interface e.g. comparing() and thenComparing()

These methods can be used to sort objects on multiple fields. They allow you to compose Comparator by using different keys. 

Writing a Comparator in Java 8 is also easier because you don't need to use Anonymous class anymore, you can write an implementation of Comparator interface in just one line by using lambda expression and method reference as you will see in this article. 

The ArrayList we'll sort

In order to demonstrate different examples of sorting List, Array, and ArrayList in Java 8, we need a list of objects. We'll use list of Items, where Item is our business object containing Id, title, price, and deliver date. 

This makes it ideal for sorting and it is also very close to any real world domain object you will see in your projects e.g. Order, Trade, Instrument etc. 

The Item class

This class implements Comparable method to provide natural order for sorting. The order is based upon Id, because Id is unique for each Item. That makes the compareTo() implementation really easy, as you just need to compare Id of items and you can subtract Id to find which one is greater. 

This logic works because Id is always positive value. Don't use this shortcut if you are not sure if Id is always positive, alternatively, you can use Integer.compare() method of JDK 7. 

class Item implements Comparable < Item > {
    private String title;
    private int Id;
    private int price;

    public Item(String title, int id, int price) {
        super();
        this.title = title;
        Id = id;
        this.price = price;
    }

    public String getTitle() {
        return title;
    }
    public int getId() {
        return Id;
    }
    public int getPrice() {
        return price;
    }

    public void setTitle(String title) {
        this.title = title;
    }
    public void setId(int id) {
        Id = id;
    }
    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return String.format(Id + "-" + title + "-" + price);
    }

    @Override
    public int compareTo(Item o) {
        return this.Id - o.Id;
    }


}


and here is the List of Item objects we'll sort in this article:

List<Item> listOfItems = new ArrayList<Item>();
listOfItems.add(new Item(1, "Effective Java", 39));
listOfItems.add(new Item(4, "Amazon Kindle Fire", 69));
listOfItems.add(new Item(2, "iPhone 7 Plus", 1009));
listOfItems.add(new Item(5, "Apple Watch", 399));
listOfItems.add(new Item(4, "IntelliJ IDEA", 89));

We'll sort this list of objects using various methods like List.sort() , Collections.sort(), Stream.sorted() method and different Comparator implementations like Comparator.reverseOrder() to sort a List in reverse order in Java

6 ways to sort List and Array in Java? List.sort() + Collections.sort() Example Tutorial




1. How to sort ArrayList in Java 8 in ascending order?

You can sort an ArrayList of objects e.g. ArrayList of String or ArrayList of Integer into ascending order by leveraging their natural order provided by Comparable interface. If you know both String and Integer implements compareTo() method which provides lexicographic order to String and numeric order to Integers.

Suppose you decide to use the List.sort() method of Java 8 API to sort an ArrayList in ascending order, then here is the code:

listOfItems.sort(null);

The sort method accepts a Comparator, but if you want to sort in the natural order you can pass null. Here is the output of this code:

Output
list before sorting: [
1-Effective Java-39, 
4-Amazon Kindle Fire-69, 
2-iPhone 7 Plus-1009, 
5-Apple Watch-399, 
4-IntelliJ IDEA-89]

list after sorting (in Java 8): [
1-Effective Java-39, 
2-iPhone 7 Plus-1009, 
4-Amazon Kindle Fire-69, 
4-IntelliJ IDEA-89, 
5-Apple Watch-399]

You can see that list is now sorted in the ascending order of Id, which is the natural order. Earlier, the order was random, actually the insertion order



2. How to sort ArrayList in Java in descending order?

In order to sort an ArrayList or List in descending order, we just need to provide a Comparator which reverse the order of original Comparator. 

If we are sorting in natural order then we can use Collections.revrerseOrder() or Compartor.reverseOrder() method which is newly added into Java 8, as shown in following example:

listOfItems.sort(Comparator.reverseOrder());

The Comparator.reverseOrder() method returns a comparator that imposes the reverse of the natural ordering. The returned comparator is also serializable and throws NullPointerException when comparing nulls

This is equivalent of Collections.reverseOrder(). If you are not using Java 8, then you can use Collections.reverseOrder()


3. How to sort an ArrayList in Java with custom objects

In most of the example of sorting array, list of ArrayList you will find on internet, people uses String and Integer objects to demonstrate sorting, which is very easy but not really helpful when it comes to sort real world domain objects e.g. Item. 

That's why I have chose a custom object which contains both String and int attributes. You could make it even more useful by adding a Date field called deliveryDate, but so far examples we have seen is about sorting a list of objects

To change things a little bit, let's me show you how you can sort a list of Objects by using Collections.sort() method, which is my preferred way because it works on every single Java version out there. 

Collections.sort(listOfItems);

This method is again overloaded and if you want to provide a Comparator, you can. For example, to sort the same list of items in the reverse order, we can provide a reverse Comparator by using Collections.reverseOrder() as shown below:

Collections.sort(listOfItems, Collections.reverseOrder());

This is how objects are traditionally sorted in Java applications. From JDK 8, you can use List.sort() as preferred way to sort a list of objects.



4. How to sort an ArrayList in Java using Comparator?

So far, we have seen examples of sorting ArrayList of objects in Java but on their natural order. Sometime you want to sort list in some custom order. You can do so by using Comparator. 

Earlier, we have to use Anonymous class to create Comparator implementation but in Java 8, things have become more simpler because of lambda expression and method reference. 

For example, if you want to sort list of Items on their title then you can pass a custom Comparator to List.sort() method as shown below:

Collections.sort(listOfItems, Comparator.comparing((Item i) -> i.getTitle()));

The Comparator.comparing() is a new method added in java.util.Comparator interface by taking advantage of fact that interface can now contain concrete methods in form of default and static methods. 

This method accept a key extractor and return a Comparator. This will print items in the ascending order of their name which is provided by this Comparator implementation.

Output
list before sorting: [1-Effective Java-39, 4-Amazon Kindle Fire-69, 2-iPhone 7 Plus-1009, 5-Apple Watch-399, 4-IntelliJ IDEA-89]
list after sorting (in Java 8): [4-Amazon Kindle Fire-69, 5-Apple Watch-399, 1-Effective Java-39, 4-IntelliJ IDEA-89, 2-iPhone 7 Plus-1009]
How to sort ArrayList in Java 8 using Stream

You can even simplify the above code by using method reference feature of Java 8 as shown below:

Collections.sort(listOfItems, Comparator.comparing(Item::getTitle));

If you want to store reference of this Comparator for future use, you can also do so, as shown in following code:

Comparator<Item> compareByTitle = Comparator.comparing(Item::getTitle);

This way, you can sort the list of objects into any parameter e.g. if you want to sort them based upon their price, you can just change the Item::getTitle to Item::getPrice and you are done. The method reference and comparing() method really makes it easy to sort object on any parameter in Java 8. 


5. How to sort ArrayList of User objects on Any Field

Sometimes, you need to sort objects into multiple fields e.g. initially you want to sort Items on their price but if price is same then you want to sort them based upon their title. 

Prior to Java 8, you need to write nested logic to check that in your compare() or compareTo() method, but from Java 8 onwards, you can chain Comparators to sort objects on multiple parameters. 

The java.util.Comparator of JDK 8 also provides a method called thenComparing(), which can be used to chain comparators along with Comparator.comparing() method. 

Here is an example to sort Item object first on price, then on title and finally on Id. So, if two items will have same price, they will be sorted on their title, and if two have same title then Id will be used for sorting:

listOfItems.sort(listOfItems, Comparator.comparing(Item::getPrice)
.thenComparing(Item::getTitle)
.thenComparing(Item::getId));

This is an amazing feature because you can compose Comparator on the fly. You can change order as you wish.


6. How to sort List in Java 8 using Stream in Java?

Last but not the least, you can also use java.uti.stream.Stream class to sort a list of objects in Java 8. The Stream class provides a sorted() method which can sort the Stream and then you can use Collectors to collect list of objects into any Collection you wish e.g. an ArrayList. 

Here is the sample code to show that:

listOfItems.stream().sorted().collect(Collectors.toCollection(ArrayList<Item>:: new))

Here we are getting first a Stream from list and then sorting it using sorted() method and then collecting elements using collect() method. We are using Collectors.toCollection() to collect items on an ArrayList by providing a constructor reference.


Java Program to sort an ArrayList in Java 8

Now, here is our complete Java program to sort an ArrayList in Java and demonstrating all the methods which we have discussed so far.

public class Main {

    public static void main(String[] args) throws Exception {

        List < String > loans = new ArrayList < > ();
        loans.add("personal loan");
        loans.add("home loan");
        loans.add("auto loan");
        loans.add("credit line loan");
        loans.add("mortgage loan");
        loans.add("gold loan");

        // printing ArrayList before removing any element
        System.out.println(loans);

        // sorting ArrayList in ascending order using collections
        Collections.sort(loans);

        // printing ArrayList after sorting in ascending order
        System.out.println("sorted list in ascending order: " + loans);

        // sorting ArrayList in descending order
        Collections.sort(loans, Collections.reverseOrder());

        // printing ArrayList after sorting in descending order
        System.out.println("sorted list in descending order: " + loans);

        // sorting ArrayList without Collections
        loans.sort(null);

        // sorting ArrayList using Stream in Java 8
        loans = loans.stream()
                     .sorted()
                      .collect(Collectors.toCollection(ArrayList < String > ::new));

    }

}

Output
[personal loan, home loan, auto loan, credit line loan, mortgage loan, gold loan]
sorted list in ascending order: [auto loan, credit line loan, gold loan, home loan, mortgage loan, personal loan]
sorted list in descending order: [personal loan, mortgage loan, home loan, gold loan, credit line loan, auto loan]


That's all about how to sort an ArrayList in Java. We have seen different ways to sort an ArrayList with ascending and descending order using Collections.sort() method. You have also learned how to sort an ArrayList using newly added sort() method from java.util.List interface. 

We have also touched based sorting list without using collections and using Stream of Java 8, and finally, you have also learned how to sort an ArrayList of objects using Comparator.

Other Java and Collections Tutorials you may like
  • How to sort the HashMap by values in Java 8? (example)
  • Difference between abstract class and interface in Java 8? (answer)
  • 5 Books to Learn Java 8 from Scratch (books)
  • How to use peek() method in Java 8 (example)
  • What is the default method in Java 8? (example)
  • 5 Free Courses to learn Java 8 and 9 (courses)
  • How to convert List to Map in Java 8 (solution)
  • How to sort the map by keys in Java 8? (example)
  • How to format/parse the date with LocalDateTime in Java 8? (tutorial)
  • 20 Examples of Date and Time in Java 8 (tutorial)
  • How to use filter() method in Java 8 (tutorial)
  • How to join String in Java 8 (example)
  • How to use Stream class in Java 8 (tutorial)
  • 7 Best Collections and Stream Courses for Java developers (courses)
Thanks for reading this tutorial so far. If you like this Java Sorting tutorial then please share with your friends and colleagues. If you have any questions or feedback please drop a comments. 

And lastly, one question for you? Which one is your favorite Collection class in Java? ArrayList, HashMap, LinkedList, ConcurrentHashMap, BlockingQueue or anything else?

1 comment :

Anonymous said...

Awesome post Javin, thanks forshar sharing it. I struggle to create custom comparator before Java 8 but with comparing(), thenComparing() and Integer.compare() method its much easier now.

Post a Comment