You have to implement a Wrapper class with comparable interface for this to happen.

To implement a custom sort order for sObjects in lists, create a wrapper class for the sObject and implement the Comparable interface. The wrapper class contains the sObject in question and implements the compareTo method, in which you specify the sort logic.

Eg:

global class OpportunityWrapper implements Comparable {

    public Opportunity oppy;

    // Constructor
    public OpportunityWrapper(Opportunity op) {
        oppy = op;
    }

    // Compare opportunities based on the opportunity amount.
    global Integer compareTo(Object compareTo) {
        // Cast argument to OpportunityWrapper
        OpportunityWrapper compareToOppy = (OpportunityWrapper)compareTo;

        // The return value of 0 indicates that both elements are equal.
        Integer returnValue = 0;
        if (oppy.Amount > compareToOppy.oppy.Amount) {
            // Set return value to a positive value.
            returnValue = 1;
        } else if (oppy.Amount < compareToOppy.oppy.Amount) {
            // Set return value to a negative value.
            returnValue = -1;
        }

        return returnValue;       
    }
}

And then to Sort just call Sort Method after adding records to your wrapper list

        OpportunityWrapper[] oppyList = new List<OpportunityWrapper>();
        Date closeDate = Date.today().addDays(10);
        oppyList.add( new OpportunityWrapper(new Opportunity(
            Name='Edge Installation',
            CloseDate=closeDate,
            StageName='Prospecting',
            Amount=50000)));
        oppyList.add( new OpportunityWrapper(new Opportunity(
            Name='United Oil Installations',
            CloseDate=closeDate,
            StageName='Needs Analysis',
            Amount=100000)));
        oppyList.add( new OpportunityWrapper(new Opportunity(
            Name='Grand Hotels SLA',
            CloseDate=closeDate,
            StageName='Prospecting',
            Amount=25000)));

        // Sort the wrapper objects using the implementation of the 
        // compareTo method.
        oppyList.sort();

So in your case, the CaseWrapper will compare CUID__c to determine sorting order in the compareTo method.

Src: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_list_sorting_sobject.htm

Answer from Pranay Jaiswal on Stack Exchange
🌐
Apex Hours
apexhours.com › home › salesforce developer › sorting in apex and javascript
Sorting in Apex and JavaScript - Apex Hours
The first choice when it comes to sorting things in Apex is generally to write a SOQL query with an ORDER BY clause. However, sometimes you need to sort records without fetching them from the database or even sort objects that are not records.
Published   September 5, 2022
Top answer
1 of 3
16

You have to implement a Wrapper class with comparable interface for this to happen.

To implement a custom sort order for sObjects in lists, create a wrapper class for the sObject and implement the Comparable interface. The wrapper class contains the sObject in question and implements the compareTo method, in which you specify the sort logic.

Eg:

global class OpportunityWrapper implements Comparable {

    public Opportunity oppy;

    // Constructor
    public OpportunityWrapper(Opportunity op) {
        oppy = op;
    }

    // Compare opportunities based on the opportunity amount.
    global Integer compareTo(Object compareTo) {
        // Cast argument to OpportunityWrapper
        OpportunityWrapper compareToOppy = (OpportunityWrapper)compareTo;

        // The return value of 0 indicates that both elements are equal.
        Integer returnValue = 0;
        if (oppy.Amount > compareToOppy.oppy.Amount) {
            // Set return value to a positive value.
            returnValue = 1;
        } else if (oppy.Amount < compareToOppy.oppy.Amount) {
            // Set return value to a negative value.
            returnValue = -1;
        }

        return returnValue;       
    }
}

And then to Sort just call Sort Method after adding records to your wrapper list

        OpportunityWrapper[] oppyList = new List<OpportunityWrapper>();
        Date closeDate = Date.today().addDays(10);
        oppyList.add( new OpportunityWrapper(new Opportunity(
            Name='Edge Installation',
            CloseDate=closeDate,
            StageName='Prospecting',
            Amount=50000)));
        oppyList.add( new OpportunityWrapper(new Opportunity(
            Name='United Oil Installations',
            CloseDate=closeDate,
            StageName='Needs Analysis',
            Amount=100000)));
        oppyList.add( new OpportunityWrapper(new Opportunity(
            Name='Grand Hotels SLA',
            CloseDate=closeDate,
            StageName='Prospecting',
            Amount=25000)));

        // Sort the wrapper objects using the implementation of the 
        // compareTo method.
        oppyList.sort();

So in your case, the CaseWrapper will compare CUID__c to determine sorting order in the compareTo method.

Src: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_list_sorting_sobject.htm

2 of 3
4

In 2024 things have improved. Salesforce introduced the Comparator interface, something that Java had at least since version 1.2. No need for wrappers or another query. In order to sort according to a field CUID__c of the Case object, you'd implement a class like this:

public class CaseCUIDComparator implements Comparator<Case> {
    public Integer compare(Case case0, Case case1) {
        if(case0.CUID__c == null) return 1;
        if(case1.CUID__c == null) return -1;
        return case0.CUID__c < case1.CUID__c ? -1 : 1;
    }
}

The unit test demonstrates its use and its impact:

@IsTest
private static void verifyComparator() {
    List<Case> cases = new List<Case>{
        new Case(CUID__c = 'B'),
        new Case(CUID__c = null),
        new Case(CUID__c = 'A'),
        new Case(CUID__c = 'D'),
        new Case(CUID__c = 'A'),
        new Case(CUID__c = 'C')
    };

    Test.startTest();
    cases.sort(new CaseCUIDComparator());
    Test.stopTest();

    Assert.areEqual('A', cases[0].CUID__c);
    Assert.areEqual('A', cases[1].CUID__c);
    Assert.areEqual('B', cases[2].CUID__c);
    Assert.areEqual('C', cases[3].CUID__c);
    Assert.areEqual('D', cases[4].CUID__c);
    Assert.areEqual(null, cases[5].CUID__c);
}
🌐
Focus on Force
focusonforce.com › development › sorting-lists-in-salesforce
Sorting Lists in Salesforce
Contacts from other departments are then listed, that have a phone number. Then comes another Finance contact, as even though it doesn’t have a phone number, the contacts in the Finance department are ordered higher than other departments if all else is the same. The last Finance contact is second last, as the Do Not Call flag is ticked. ... Share it with your network! ... Another way to sort on multiple fields in APex is to write your data to a table used to store data temporarily and then simply retrieve the same data again in a list using SOQL and use the ‘order by’ clause to sort the way you want.
🌐
Jamessimone
jamessimone.net › blog › joys-of-apex › sorting-and-performance-in-apex
Joys Of Apex: Sorting And Performance In Apex
By passing the Comparator instance using the this keyword, we completely eliminate the static method and instead allow consumers of custom sorting to simply define their sorting algorithm in a class extending Comparator prior to calling the sort method with their list. That’s properly object-oriented. Edit - as of the Winter ‘24 release, Apex now ships with System.Comparable as an interface.
Top answer
1 of 2
4

You really should bulkify this code, i.e. not run a query inside a loop which could cause potentially cause issues with the governor limits, and since you just want the combined list for all Job__c records this makes your ordering easy too — you can do it in the query!

The code you want to change is this:

// Select relevant Job Occurrence objects 
List<Job_Occurrence__c> jobOccuList = new List<Job_Occurrence__c>();

for (Job__c job : jobList) {  

     Job_Occurrence__c jobOccurrence = [SELECT Id, Job__c,  
                                               Schedule_Start_Date__c 
                                        FROM Job_Occurrence__c 
                                        WHERE Job__c =: job.Id];

     if((jobOccurrence != null) && (jobOccurrence.Id != null)) {
        jobOccuList.add(jobOccurrence);
     }        
}

Essentially we can optimise this to not only use one query instead of N (where N is jobList.size()) and get them ordered at the same time. First we need to gather the list of Job__c IDs, and then we can use the IN statement in the WHERE clause of the SOQL:

// Select relevant Job Occurrence objects 
List<Job_Occurrence__c> jobOccuList;
Set<Id> setJobIds = new Set<Id>();

setJobIds.addAll(jobList);

// get the job occurances starting with the latest, use ASC for reverse!
jobOccuList = [SELECT Id, Job__c, Schedule_Start_Date__c 
               FROM   Job_Occurrence__c 
               WHERE  Job__c IN : setJobIds
               ORDER BY Schedule_Start_Date__c DESC];

Finally, if you need to be able to easily map back from the Job_Occurrence_c records to Job_c records, you could replace the set with a map as below, though given that you just want this list I don't think it's needed here (just providing it for completeness).

Map<Id, Job__c> mapJobs = new Map<Id, Job__c>();

for (Job__c job : jobList) {
    mapJobs.put(job.Id, job);
}

** snip **

for (Job_Occurrence__c jobOccu : jobOccuList) {
    Job__c theJob = mapJobs.get(jobOccu.Job__c);
    // do stuff with the job
}

All of this code has been written in browser, so there may be some syntax errors but it should be good!

2 of 2
-2

You can try :

liDates.sort(); 

It's working for me.

Cheers

Find elsewhere
🌐
YouTube
youtube.com › sfdc stop
Sort a list of sObject records based on a field value | Salesforce Apex Tutorial Series by SFDC Stop - YouTube
Hello Trailblazers, In this video we're going to learn how we can sort a list of sObject records based on a field value. In the previous two tutorials, we le...
Published   December 9, 2021
Views   4K
🌐
LinkedIn
linkedin.com › pulse › sorting-list-objects-apex-js-jigar-suthar--qlnsf
Sorting List of Objects in Apex and JS
February 21, 2024 - For Apex you have to use Comparator Interface. After the Salesforce new release, System.Comparator<sObject> Interface made the sorting of List with sObject easier than before. let's understand by example.
Top answer
1 of 3
3

This is a general approach I'd suggest you consider taking considering the nature of your data.

If you don't want to use comparable, you will need to sort based on the "major" version, followed by the "minor" (for each major version), then each "finest" version (for the minor version). That will allow you to deal with the ones that don't have finer levels or those that don't use numbers like your 5.x

Use the '.' as separators to know what portions of your string to use to sort on for each level. You may want to save the results to a map by level (or something along those lines) where you can pull the results from each out and not have deeply nested loops in your code. I would use a RegEx pattern to assist with the coding.

EDIT

In response to comments...

Note: I have not tested the code below, but it does appear that it will compile.

List<String> src = new List<String>{
            '7.1.2', '8.1.3', '11.0.5', '5.x', '10.0.89', '12.13.14'};

// declare maps and lists you will need
map<string, string>srcOrderMap = new map<string, string>();
map<string, list<string>>srcOrderLstMap = new map<string, List<string>>();

Integer count = 0;
integer iString = string.valueOf(count);
integer iString=string.valueOf(count);
list<string>b_count = new list<string>();
// create map for where you started from for complete string and list string
for(string s:src){
    b_count=b.split('.');
    srcOrderMap.put(iString,b_count);
    srcOrderMap.put(iString,s);
    count++;
}

// declare variables for next loop
map<string, string>srcCol0OrderMap = new map<string, string>();
map<string, string>srcCol1OrderMap = new map<string, string>();
map<string, string>srcCol2OrderMap = new map<string, string>();
list<string>sArrayCol0 = new list<string>();
list<string>sArrayCol1 = new list<string>();
list<string>sArrayCol2 = new list<string>();

// create maps for each column and lists of those values
for(integer s=0;s=srcOrderMap.size();s++){
    for(integer c=0;c<3;c++){

        if(c == 0){
            sArrayCol0.add.srcOrderMap.get(string.valueOf(s)[0]);
        }
        if(c == 1){
            sArrayCol1.add.srcOrderMap.get(string.valueOf(s)[1]);
        }
        if(c == 2){
            sArrayCol2.add.srcOrderMap.get(string.valueOf(s)[2]);
        }
        srcCol0OrderMap.put(string.valueOf(s), sArrayCol0[string.valueOf(s)]);
        srcCol1OrderMap.put(string.valueOf(s), sArrayCol1[string.valueOf(s)]);
        srcCol2OrderMap.put(string.valueOf(s), sArrayCol2[string.valueOf(s)]);
    }

}

Now you can do a sort on column 0, after which you can do a sub-sort on column1 where any values in column 0 are the same to determine which value gets moved up or down in your map.

// sort the values in column 0
sArrayCol0.sort();

I'll leave it to you to determine how you want to find the duplicate values in the list. There are lots of solutions to that problem you should be able to find on your own.

Once you have the sorted column 0 results, all you need to do is go back to your original source map and retrieve the original values that are also ready for you in sArrayCol1 where they're ready for you to sort() and compare. The results of that sort will determine which one of the values in Col 0 "wins". If both are equal, then you sort again on based on the values found in sArrayCol2 as once again are referenced in the original source map.

That's the reason I recommended using maps, so you can keep track of these values and will always be able to go back and reference them from where you began as you re-order your records at different levels. I hope this provides you with the "map" you need to reach your destination.

2 of 3
6

Apex has a Version class that supports major.minor and major.minor.patch numbering. If you work with those objects:

List<Version> src = new List<Version>{
    new Version(7, 1, 2),
    new Version(8, 1, 3),
    ...
};

you get sorting for free (as compareTo is implemented) where this sorts in place:

src.sort();

and the string format for each Version is as expected e.g. "7.1.2".

Note that there is no support for your "5.x" though; if you need that you will have to create your own class as David discusses.

🌐
Netsutra
netsutra.com › blog › 2018 › 11 › 29 › custom-sorting-of-a-collection-in-apex
Custom sorting of a collection in Apex – Netsutra Blog
Apex will allow you to make an order List of objects that you can then iterate over and manipulate. However, Apex will not let you use the built-in sort method for List to sort sObjects by a field inside.
🌐
Reddit
reddit.com › r/salesforce › sorting list in apex class based on list view sort order
r/salesforce on Reddit: Sorting list in Apex Class based on List View sort order
October 22, 2024 - Disclaimer: I am not a developer, so my understanding of custom code is limited. We have a custom Visualforce button on a list view for one of our custom objects. The button generates a PDF based on the selected records in the list view. The selected records are sorted by a custom date field.
🌐
Absyz
absyz.com › home › sorting of sobjects in salesforce
Sorting of sObjects in Salesforce - Absyz
November 23, 2023 - I had a requirement where I had ... field Price__c from lowest to highest. There is an instance method sort() for List collection type, it sorts the items in the list in ascending order....
🌐
Apexsandbox
apexsandbox.io › problem › 92
Apex Practice Problems - ApexSandbox.io
Become an expert Apex developer with a growing collection of Apex programming problems
🌐
SalesForce By Gvs
salesforcebygvs.wordpress.com › 2017 › 12 › 23 › list-sorting-in-apex
List sorting in apex – SalesForce By Gvs
January 13, 2018 - Standard sorting method The sort method of list class provides sorting for sObject type list. There is a standard way of sorting, for instance if a list of account is being sorted and the account contains name field in the list the sorting will ...
🌐
GitHub
github.com › ChuckJonas › apex-sort-sobs
GitHub - ChuckJonas/apex-sort-sobs: Library for short hand sorting of Salesforce SObjects by any field
Account[] accs = [SELECT My_Custom_Field__c FROM Account LIMIT 2000]; SortSobs.descending(accs, Account.My_Custom_Field__c); ... List<Contact> entries = [SELECT Name, Account.Name FROM Contact LIMIT 2000]; SortSobs.ascending(entries, SObjectField[]{ Contact.Account, Account.Name });
Starred by 20 users
Forked by 12 users
Languages   Apex 100.0% | Apex 100.0%
🌐
Salesforce Developers
developer.salesforce.com › forums
Sort Order for Apex List
Skip to main content · Join us as TDX comes to London! Over two days, experience the developer conference for the AI agent era. Become an Agentblazer and gain the critical skills needed to build the future of software with Agentforce. Register Now
🌐
GitHub
github.com › pozil › apex-sorting
GitHub - pozil/apex-sorting: Sample Code for Sorting in Apex
This repository contains sample code for advanced sorting with Apex. It presents two approaches that go beyond the default List.sort method.
Starred by 13 users
Forked by 7 users
Languages   Apex 100.0% | Apex 100.0%