Compare Long Collections & Sort Example
Sorting is a fundamental operation in Java programming, especially when dealing with collections of data. When working with lists of Long
values, developers often need to define custom sorting behaviors such as descending order, null handling, or even sorting based on custom object properties. Let us delve into understanding how to compare Long
values in Java, sort them efficiently, and work with collections during the process.
1. Introduction
Sorting in Java refers to the process of arranging elements in a specific order—typically ascending or descending—based on natural ordering or a custom-defined logic. Sorting helps improve readability, searchability, and overall data management in applications that handle collections of objects, numbers, or strings. Java provides powerful tools and APIs to sort collections, including arrays and List
implementations.
1.1 Understanding Collections.sort() in Java
The Collections.sort()
method is a utility provided by the java.util.Collections
class to sort elements of a List
in place. It has two overloaded versions:
Collections.sort(List<T> list)
: Sorts the list in ascending order according to the natural ordering of its elements. The elements must implement theComparable
interface.Collections.sort(List<T> list, Comparator<? super T> c)
: Sorts the list according to the order defined by the specifiedComparator
.
The sorting is stable and uses a modified mergesort algorithm that provides guaranteed O(n log n)
performance. When using custom logic for sorting (like descending order, multiple criteria, or object properties), you typically provide a Comparator
implementation.
1.2 The Comparator Interface
The Comparator
interface belongs to the java.util
package and provides a way to define custom sorting logic for objects. It contains the method compare(T o1, T o2)
which returns:
< 0
: ifo1
is less thano2
0
: ifo1
equalso2
> 0
: ifo1
is greater thano2
Since Java 8, Comparator
has become more powerful with static and default methods such as:
Comparator.comparing()
: Builds a comparator using a key extractor functionComparator.reverseOrder()
: Sorts in reverse natural orderComparator.nullsFirst()
andComparator.nullsLast()
: Define hownull
values should be handledthenComparing()
: Allows chaining of multiple comparators
These enhancements allow developers to create clean and readable sorting logic without needing verbose comparator classes.
2. Code Example
This example walks you through different sorting scenarios using Java’s Collections.sort()
method along with Comparator
. You’ll learn how to:
- Handle
null
values during comparison - Sort in both ascending and descending order
- Use custom logic (like sorting by the last digit of a salary)
- Chain comparators for multi-level sorting
Each step demonstrates a practical way to write clean, null-safe, and flexible comparators when dealing with Long
fields in Java collections.
import java.util.*; // Step 1: Define the Employee class class Employee { String name; Long salary; Employee(String name, Long salary) { this.name = name; this.salary = salary; } @Override public String toString() { return name + " ($" + salary + ")"; } } class Main { public static void main(String[] args) { // Step 2: Create a list of Employees with diverse salary endings List<Employee> employees = Arrays.asList(new Employee("Alice", 50001L), // Ends with 1 new Employee("Bob", 75002L), // Ends with 2 new Employee("Charlie", 60013L), // Ends with 3 new Employee("David", null), // null salary new Employee("Eve", 43004L), // Ends with 4 new Employee("Frank", 55009L), // Ends with 9 new Employee("Grace", 12345L), // Ends with 5 new Employee("Heidi", 88000L), // Ends with 0 new Employee("Ivan", 70007L), // Ends with 7 new Employee("Judy", 99008L), // Ends with 8 new Employee("Tom", 45001L), // Ends with 1 new Employee("Sam", 46001L) // Also ends with 1 ); // Step 3: Sort by salary (Natural Order) System.out.println("1. Sorted by salary (Natural Order):"); Collections.sort(employees, Comparator.comparing( e -> e.salary, Comparator.nullsLast(Comparator.naturalOrder()))); employees.forEach(System.out::println); // Step 4: Sort by salary in Descending Order System.out.println("\n2. Sorted by salary (Descending):"); Collections.sort(employees, Comparator.comparing( e -> e.salary, Comparator.nullsLast(Comparator.reverseOrder()))); employees.forEach(System.out::println); // Step 5: Sort by last digit of salary System.out.println("\n3. Sorted by last digit of salary:"); Collections.sort(employees, Comparator.comparing( e -> e.salary == null ? Long.MAX_VALUE : e.salary % 10)); employees.forEach(System.out::println); // Step 6: Sort by last digit of salary, then by salary System.out.println("\n4. Sorted by last digit, then salary:"); Collections.sort(employees, Comparator .comparing((Employee e) -> e.salary == null ? Long.MAX_VALUE : e.salary % 10) .thenComparing( e -> e.salary, Comparator.nullsLast(Long::compareTo))); employees.forEach(System.out::println); // Step 7: Sort with nulls first System.out.println("\n5. Null salary first, then ascending:"); Collections.sort(employees, Comparator.comparing( e -> e.salary, Comparator.nullsFirst(Long::compareTo))); employees.forEach(System.out::println); } }
2.1 Code Explanation
The given Java program demonstrates various ways to sort a list of Employee
objects based on their Long
salary values using Collections.sort()
and custom Comparator
logic. The Employee
class has two fields—name
and salary
—and overrides toString()
for readable output. In the main()
method, a list of employees is created with some having null
salaries. The program first sorts the list in natural ascending order by salary using Comparator.comparing()
with nullsLast()
to handle nulls at the end. It then sorts salaries in descending order using Comparator.reverseOrder()
. Next, it demonstrates sorting by the last digit of each salary by extracting the modulus of 10 and safely handling nulls by assigning Long.MAX_VALUE
. A multi-criteria sort is performed by first comparing the last digit and then the full salary using thenComparing()
. Finally, it shows sorting with null salaries appearing first using nullsFirst()
. This code illustrates real-world scenarios of sorting numeric values with custom rules, null safety, and object property comparisons in Java.
2.2 Code Output
1. Sorted by salary (Natural Order): Grace ($12345) Eve ($43004) Tom ($45001) Sam ($46001) Alice ($50001) Frank ($55009) Charlie ($60013) Ivan ($70007) Bob ($75002) Heidi ($88000) Judy ($99008) David ($null) 2. Sorted by salary (Descending): Judy ($99008) Heidi ($88000) Bob ($75002) Ivan ($70007) Charlie ($60013) Frank ($55009) Alice ($50001) Sam ($46001) Tom ($45001) Eve ($43004) Grace ($12345) David ($null) 3. Sorted by last digit of salary: Heidi ($88000) Alice ($50001) Sam ($46001) Tom ($45001) Bob ($75002) Charlie ($60013) Eve ($43004) Grace ($12345) Ivan ($70007) Judy ($99008) Frank ($55009) David ($null) 4. Sorted by last digit, then salary: Heidi ($88000) Tom ($45001) Sam ($46001) Alice ($50001) Bob ($75002) Charlie ($60013) Eve ($43004) Grace ($12345) Ivan ($70007) Judy ($99008) Frank ($55009) David ($null) 5. Null salary first, then ascending: David ($null) Grace ($12345) Eve ($43004) Tom ($45001) Sam ($46001) Alice ($50001) Frank ($55009) Charlie ($60013) Ivan ($70007) Bob ($75002) Heidi ($88000) Judy ($99008)
3. Conclusion
Sorting Long
values in Java can be straightforward or highly customizable depending on your needs. From natural ordering and descending sorting to handling nulls and sorting based on object fields, Java’s Comparator
API and Collections.sort()
provide a rich toolkit. Understanding these concepts is essential for writing clean and effective Java code.