Sudipta Deb

Sudipta Deb

Founder of Technical Potpourri, Co-Founder of Shrey Tech, Enterprise Cloud Architect

🚀 Get ready for the exciting new feature coming with Salesforce’s Winter ’24 release! In this blog post, I will dive deep into how this update is set to revolutionize the way you sort list elements within your Salesforce code.

đź“‘ With the Winter ’24 release, the List class receives a significant upgrade by introducing support for the all-new Comparator interface. This powerful enhancement empowers developers to implement a wide range of sorting orders effortlessly using the List.sort() method with a Comparator parameter.

đź’ˇ I will walk you through the ins and outs of using this feature, demonstrating its incredible versatility and practicality. Whether you need to sort lists of custom objects or standard data types, the Comparator interface offers a flexible solution for every sorting scenario.

If you prefer watching videos, you can watch my YouTube video covering these enhancements below.

Introduction

The List class now supports the new Comparator interface, so you can implement different sort orders in your code by using List.sort() with a Comparator parameter. To perform locale-sensitive comparisons and sorting, use the getInstance method in the new Collator class. Because locale-sensitive sorting can produce different results depending on the user running the code, avoid using it in triggers or in code that expects a particular sort order.

How

Implement the compare() method of the System.Comparator interface, and specify the Comparator as a parameter to List.sort(). Your implementation must explicitly handle null inputs in the compare() method to avoid a null pointer exception. This example implements two different ways of sorting employees.

Example 1 – Sorting Based On String Comparison

Here is the Student Class which has studentId, studentName and studentAge as member variables. Constructor of the class is instantiating the class and finally the two member functions getStudentName() and getStudentAge are returning student’s name and age respectively.

 

public class Student {
 private Integer studentId;
 private String studentName;
 private Integer studentAge; 
 // Constructor
 public Student(Integer studentId, String studentName, Integer studentAge) {
 this.studentId = studentId;
 this.studentName = studentName;
 this.studentAge = studentAge;
 } 
 public String getStudentName() { return studentName; }
 public Integer getStudentAge() { return studentAge; }
}

Now consider a list containing the below students with their details. The question is how can we sort the list elements which is all the students based on their names?

List<Student> allStudents = new List<Student>();
allStudents.add(new Student(101,'Joe Smith', 14));
allStudents.add(new Student(102,'Shane Smith', 6));
allStudents.add(new Student(25,'Caragh Smith', 9));
allStudents.add(new Student(105,'Mario Ruiz', 11));

Now to sort the above list based on Student name, I can write my own Comparator class after Winter 24 Release. Inside the comparator class, I will be writing my own custom logic to perform the comparison between two list elements. Here is the custom comparator class.

public class StudentNameCompare implements Comparator<Student>{ 
 public Integer compare(Student s1, Student s2){
 if(s1?.getStudentName() == null && s2?.getStudentName() == null){
 return 0;
 }else if(s1?.getStudentName() == null){
 return -1;
 }else if(s2?.getStudentName() == null){
 return 1;
 }
 return s1.getStudentName().compareTo(s2.getStudentName());
 }
}

The important thing to remember is the Comparator interface. The class where the sorting/compare logic will be written should implement the Comparator interface. Then the compare function is the main section where the compare logic will be written.

With that, below is the test class to make sure lists are being sorted as per the logic writte.

@isTest
private class StudentCompareTest {
 @isTest static void testSortStudentByName() {
 List<Student> allStudents = new List<Student>();
 allStudents.add(new Student(101,'Joe Smith', 14));
 allStudents.add(new Student(102,'Shane Smith', 6));
 allStudents.add(new Student(25,'Caragh Smith', 9));
 allStudents.add(new Student(105,'Mario Ruiz', 11));
 StudentNameCompare studentNameCompare = new StudentNameCompare();
 allStudents.sort(studentNameCompare);
 Assert.areEqual('Caragh Smith', allStudents.get(0).getStudentName());
 Assert.areEqual('Joe Smith', allStudents.get(1).getStudentName());
 Assert.areEqual('Mario Ruiz', allStudents.get(2).getStudentName());
 Assert.areEqual('Shane Smith', allStudents.get(3).getStudentName());
 }
}

As you can see, the above test class is doing the assert based on the Student’s name sorted alphabetically.

Example 2 – Sorting Based On Integer Comparison

For this example, I will use the same Student class and the same list of students, but this time list will be sorted based on Student Age.

Here is the comparator class where inside the compare function I have written the logic to compare two students based on their age.

public class StudentAgeCompare implements Comparator<Student>{
 public Integer compare(Student s1, Student s2){
 if(s1?.getStudentAge() == null && s2?.getStudentAge() == null){
 return 0;
 }else if(s1?.getStudentAge() == null){
 return -1;
 }else if(s2?.getStudentAge() == null){
 return 1;
 }else if(s1?.getStudentAge() > s2?.getStudentAge() ){
 return 1;
 }else if(s1?.getStudentAge() < s2?.getStudentAge() ){
 return -1;
 }else{
 return 0;
 }
 }
}

With the above comparator class, below is the test class to check whether the list is properly being sorted based on student’s age.

@isTest
private class StudentCompareTest {
 @isTest static void testSortStudentByAge() {
 List<Student> allStudents = new List<Student>();
 allStudents.add(new Student(101,'Joe Smith', 14));
 allStudents.add(new Student(102,'Shane Smith', 6));
 allStudents.add(new Student(25,'Caragh Smith', 9));
 allStudents.add(new Student(105,'Mario Ruiz', 11));
 StudentAgeCompare studentAgeCompare = new StudentAgeCompare();
 allStudents.sort(studentAgeCompare);
 Assert.areEqual('Shane Smith', allStudents.get(0).getStudentName());
 Assert.areEqual('Caragh Smith', allStudents.get(1).getStudentName());
 Assert.areEqual('Mario Ruiz', allStudents.get(2).getStudentName());
 Assert.areEqual('Joe Smith', allStudents.get(3).getStudentName());
 }
}

As you can see, the above test class is doing the assert based on the Student’s age sorted.

Example 3 – Use Of Collator Class To Sort Based On The User Locale

To perform locale-sensitive comparisons and sorting, use the getInstance method in the new Collator class. Because locale-sensitive sorting can produce different results depending on the user running the code, avoid using it in triggers or in code that expects a particular sort order.

Inside the below test class, I am doing sorting based on user locale (German).

@IsTest
private class SortGermanFoods {
 @isTest static void testSorting() {
 string userLocale = 'de_DE';
 User u = new User(Alias = 'standt', Email='standarduser@testorg.com',
 EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
 LocaleSidKey=userLocale, TimeZoneSidKey='America/Los_Angeles',
 ProfileId = [SELECT Id FROM Profile WHERE Name='Standard User'].Id,
 UserName='standarduser' + DateTime.now().getTime() + '@testorg.com');
 System.runAs(u){
 List<String> foodName = new List<String> {
 'Käse',
 'Milch',
 'Öl',
 'Knödel',
 'Gemüse'
 };
 Collator myCollator = Collator.getInstance();
 foodName.sort(myCollator);
 Assert.areEqual('Gemüse', foodName[0]);
 Assert.areEqual('Käse', foodName[1]);
 Assert.areEqual('Knödel', foodName[2]);
 Assert.areEqual('Milch', foodName[3]);
 Assert.areEqual('Öl', foodName[4]); 
 }
 }
}

The important thing here is the Collector class. I am using the getInstance() method to get reference of the Collector class and then using that reference to do the sorting based on user’s locale.

Conclusion

Whether you’re a seasoned Salesforce developer or just getting started, this Winter ’24 release feature is sure to streamline your development process and make list sorting a breeze. 

Disclaimer

This article is not endorsed by Salesforce, Google, or any other company in any way. I shared my knowledge on this topic in this blog post. Please always refer to Official Documentation for the latest information.

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *