How To Sort Java Collections
1 CommentLast Updated on October 22, 2024 by jt
Sorting collections in Java is a common task. Java provides several different ways we can sort Collections.
In this article, we will discuss the options we have to sort collections in Java.
Understanding the java.util.Collections.sort() Method
The java.util.Collections.sort()
method is a crucial utility in the Java programming language, designed to order elements within a list. Found within the java.util.Collections
class, this method arranges elements in ascending order, making it an essential tool for developers working with data that requires sorting.
Key Features of Collections.sort()
- Versatility: Unlike
java.util.Arrays.sort()
, which is limited to arrays, theCollections.sort()
method can handle a variety of collection types such as linked lists, queues, and more. - No Return Value: This method operates directly on the list provided, altering its order without producing a separate sorted list.
Method Signature
public static void sort(List myList)
- Parameter:
myList
: The list to be sorted. This should be an instance of theList
interface.
How It Works
When you pass a list to Collections.sort()
, the method reorders the list elements in place, changing the original sequence to be sorted from the smallest to the largest. The sorting is based on the natural ordering of the elements, which is determined by their compareTo()
method or as defined by a Comparator. It’s efficient and seamlessly integrates with a variety of collection structures in Java.
Example of Usage
Consider you have a list with elements:
List myList = Arrays.asList("Michael Weston", "Fiona Glenanne", "Sam Axe", "Jesse Porter", "Madeline Westen");
Applying the Collections.sort()
method:
Collections.sort(myList);
Results in the sorted list:
[Fiona Glenanne, Jesse Porter, Madeline Westen, Michael Weston, Sam Axe]
This example demonstrates how Collections.sort()
arranges the elements alphabetically, demonstrating its ability to ordering list-based data structures.
Complete Example of Collections.sort()
In the example below, we take a list of 5 names and sort the list to alphabetical order.
import java.util.ArrayList;
import java.util.Collections;
public class CollectionSort
{
public static void main( String[] args )
{
ArrayList<String> list = new ArrayList<String>();
list.add("Michael Weston");
list.add("Fiona Glenanne");
list.add("Sam Axe");
list.add("Jesse Porter");
list.add("Madeline Westen");
System.out.printf("Before Sort : %s%n", list);
Collections.sort(list);
System.out.printf("After Sort : %s%n", list);
}
}
When we run the code above this is the output:
Before Sort : [Michael Weston, Fiona Glenanne, Sam Axe, Jesse Porter, Madeline Westen]
After Sort : [Fiona Glenanne, Jesse Porter, Madeline Westen, Michael Weston, Sam Axe]
The names are now in sorted alphabetical order. You can use this same method for sorting doubles, longs, and strings.
Reverse Sort with Collections.sort()
The following example is the same as the previous, except we demonstrate how you can reverse the order of the sort with Collections.sort()
.
import java.util.ArrayList;
import java.util.Collections;
/**
* Created by jt, Spring Framework Guru.
*/
public class CollectionSortReverse {
public static void main( String[] args )
{
ArrayList<String> list = new ArrayList<String>();
list.add("Michael Weston");
list.add("Fiona Glenanne");
list.add("Sam Axe");
list.add("Jesse Porter");
list.add("Madeline Westen");
System.out.printf("Before Sort : %s%n", list);
Collections.sort(list, Collections.reverseOrder());
System.out.printf("After Sort : %s%n", list);
}
}
Sorting Objects with a Comparator
To help us sort objects, Collections.sort() can utilize a Comparator to allow us to specify custom sort criteria.
You can see for the output, we are using Java’s versatile printf() method.
Person Class
For our demonstration of using a Comparator, we’ll implement a simple Person POJO.
public static class Person {
private String firstName;
private String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// getters and setters ommitted
}
Comparator Implementation
To create a Comparator, we need to provide an implementation of the java.util.Comparator
class.
In this example, we are comparing the firstName
property of our Person
POJO.
public static class CompareFirstName implements java.util.Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.getFirstName().compareTo(o2.getFirstName());
}
}
Collections.sort() with Comparator Example
In the following example, we create a list of 5 Person
objects, and use the Comparator
implementation to sort the list by firstName
.
public static void main( String[] args )
{
ArrayList<Person> list = new ArrayList<Person>();
list.add(new Person("Michael", "Weston"));
list.add(new Person("Fiona", "Glenanne"));
list.add(new Person("Sam", "Axe"));
list.add(new Person("Jesse", "Porter"));
list.add(new Person("Madeline", "Westen"));
System.out.printf("Before Sort : %s%n", list);
Collections.sort(list, new CompareFirstName());
System.out.printf("After Sort : %s%n", list);
}
--------------------output-----------------------
Before Sort : [{firstName='Michael', lastName='Weston'}, {firstName='Fiona', lastName='Glenanne'}, {firstName='Sam', lastName='Axe'}, {firstName='Jesse', lastName='Porter'}, {firstName='Madeline', lastName='Westen'}]
After Sort : [{firstName='Fiona', lastName='Glenanne'}, {firstName='Jesse', lastName='Porter'}, {firstName='Madeline', lastName='Westen'}, {firstName='Michael', lastName='Weston'}, {firstName='Sam', lastName='Axe'}]
Collections.sort() Lambda Example
We can also use a Java Lambda expression as the Comparator. In the following example we sort the list of 5 person objects by the lastName property.
public class CollectionSortLambda {
public static void main( String[] args )
{
ArrayList<Person> list = new ArrayList<Person>();
list.add(new Person("Michael", "Weston"));
list.add(new Person("Fiona", "Glenanne"));
list.add(new Person("Sam", "Axe"));
list.add(new Person("Jesse", "Porter"));
list.add(new Person("Madeline", "Westen"));
System.out.printf("Before Sort : %s%n", list);
Collections.sort(list, (p1, p2) -> p1.getLastName().compareTo(p2.getLastName()));
System.out.printf("After Sort : %s%n", list);
}
}
-----------------output-------------------
Before Sort : [{firstName='Michael', lastName='Weston'}, {firstName='Fiona', lastName='Glenanne'}, {firstName='Sam', lastName='Axe'}, {firstName='Jesse', lastName='Porter'}, {firstName='Madeline', lastName='Westen'}]
After Sort : [{firstName='Sam', lastName='Axe'}, {firstName='Fiona', lastName='Glenanne'}, {firstName='Jesse', lastName='Porter'}, {firstName='Madeline', lastName='Westen'}, {firstName='Michael', lastName='Weston'}]
Arrays.sort() vs Collections.sort()
A common alternative to Collections.sort()
is Arrarys.sort()
. While similar in functionality, there are some important differences to understand.
Data Types
- Arrays.sort(): This method can handle arrays containing both primitive data types (such as
int
,char
, anddouble
) and object references. It directly manipulates the elements within the array. - Collections.sort(): This is designed primarily for sorting objects within collections like
ArrayList
,LinkedList
, and other data structures implementing theList
interface. It does not work with primitive data types directly.
Usage
- Use Arrays.sort() when you have n array. It is efficient and leverages direct access to array elements.
- Use Collections.sort() when working with objects in any class that implements the
Collection
framework. This method requires creating a list from arrays if you want to sort an array’s elements.
Time Complexity
- Arrays.sort(): Implements a Dual-Pivot Quicksort algorithm, providing a time complexity of O(N log N). Dual-Pivot Quicksort generally outperforms traditional quicksort algorithms due to its improved pivot selection.
- Collections.sort(): Utilizes an adaptive Mergesort algorithm. While the average performance also stands at O(N log N), this method first transforms the collection into an array before sorting, which can add overhead.
Performance Considerations
- For sorting arrays of primitive types, Arrays.sort() is typically more efficient, given that it avoids additional manipulations and works directly with array memory.
- However, when dealing with objects, Collections.sort() provides a cleaner and more flexible solution as it accommodates objects with defined ordering through the
Comparable
orComparator
interfaces.
In summary, you should choose Arrays.sort()
for optimal performance with primitive arrays, and use on Collections.sort()
for more complex, object-oriented sorting needs. Also, be pragmatic in your selection. If you’re dealing with small collections, the performance difference isn’t significant. However, with larger collections the difference will be more apparent.
Performance of Arrays.sort() vs Collections.sort()
In this example, we’ll look at the performance of Arrays.sort()
vs Collections.sort()
. In this example, we will create an array of 10,000,000 randomly generated integers.
We will then compare the time it takes to sort the array using Arrays.sort()
and compare it to the time it takes to sort the array using Collections.sort()
.
public static void main( String[] args )
{
int length = 10000000;
int[] array = new int[length];
Random random = new Random();
for (int i = 0; i < length; i++) {
array[i] = random.nextInt(0, length);
}
ArrayList<Integer> list = new ArrayList<Integer>(length);
for (int i = 0; i < length; i++) {
list.add(array[i]);
}
//Array sort
long start = System.currentTimeMillis();
Arrays.sort(array);
long end = System.currentTimeMillis();
System.out.println("Array sort took: " + (end - start) + "ms");
//Collection sort
start = System.currentTimeMillis();
Collections.sort(list);
end = System.currentTimeMillis();
System.out.println("Collection sort took: " + (end - start) + "ms");
}
The above example produces the following output.
Array sort took: 837ms
Collection sort took: 2628ms
When sorting an array with 10,000,000 elements we can see that Collections.sort() took roughly 3 times as long to execute.
The size of the array does matter for performance. Testing with 3000 elements, the performance difference is only 1 ms.
Conclusion
Java’s Collections.sort()
is a powerful tool we can use to sort Collections in Java. When performance counts, and you are working with an array of primitives, you can see the performance benefit of using Arrays.sort()
over Collections.sort()
.
The sort() method is just one utility for modifying collections. The Collections
class has a number of methods, such as shuffle
, reverse
, and max
which you can use to manipulate Collections of data. You can review these additional options in the Oracle documentation here.
The source code for this post is available here in Github.
Spring Framework 6: Beginner to Guru
Checkout my best selling course on Spring Framework 6. This is the most comprehensive course you will find on Udemy. All things Spring!
FLY.King
Are you more example for Java Collections , such as: ‘synchronizedMap’,’unmodifiableCollection’…