I have fetched assets sorted by date using SOQL query. When I do for(Asset a:lstAsset) and add a to a list, the sort order from the SOQL query is lost.

I want the sort order to be retained. Is there a way? And can someone explain how List iterator for loop works? Is it the best one to use or is there a better way?

  • 1
    How do you know that the sort order has been lost? Lists store things in the order that you insert them in, so if your List appears to be out-of-order, it's because you initially put them into the list out-of-order (or you've called List.sort()).
    – Derek F
    Dec 27, 2016 at 14:27
  • 2
    Also, if the only purpose of your loop is to insert records into a list, you should consider just directly assigning the query results to your List<Asset> instead. e.g. List<Asset> myAssets = [SELECT Id, <other fields> FROM Asset WHERE <conditions> ORDER BY myDate]
    – Derek F
    Dec 27, 2016 at 14:29
  • hi @yeselkay, please accept an answer if it helped you resolve your question. Thanks
    – glls
    Jul 30, 2017 at 16:14

2 Answers 2

public class MyClass {
  private AssetWrapper[] awList = new List<AssetWrapper>();
  public class AssetWrapper implements Comparable {
     private Asset a;
     public AssetWrapper(Asset a) {this.a = a;}
     public Integer compareTo(Object compareTo) {
        // needs bus logic to decide if null date is < non null date or vice-versa
        AssetWrapper ctA = (AssetWrapper) compareTo;
        if (ctA.someDate < this.a.someDate) return +1;
        if (ctA.someDate > this.a.someDate) return -1;
        return 0; 

   public void getAssets() {
     for (Asset a: [select ....])
        awList.add(new AssetWrapper(a));

   public void addAsset(Asset a) {awList.add(new AssetWrapper(a));}
   public void sortAssets() {awList.sort();}


  • global modifier not required
  • you can use inner class
  • You need some null checks. Also once those are done you can youse your favorite expression syntax...ternary! Doesn't the Comparable interface require the parameter type to be Object, too?
    – Adrian Larson
    Dec 27, 2016 at 20:12
  • right you are re: Object;
    – cropredy
    Dec 27, 2016 at 20:19
  • @cropredy, could you add null check to you example, please? Is it simple if (ctA.someDate == null) return -1; and if (this.a.someDate == nul) return 1;?
    – Eduard
    May 8, 2019 at 18:16
  • 1
    @Eduard - this is up to you to decide if nulls sort first or last but the approach in your comment is the way to go
    – cropredy
    May 8, 2019 at 19:18

Reference from link

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.

Below example shows how to create a wrapper class for Opportunity. The implementation of the compareTo method in this class compares two opportunities based on the Amount field—the class member variable contained in this instance, and the opportunity object passed into the method.

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;       

Below example provides a test for the OpportunityWrapper class. It sorts a list of OpportunityWrapper objects and verifies that the list elements are sorted by the opportunity amount.

private class OpportunityWrapperTest {
    static testmethod void test1() {
        // Add the opportunity wrapper objects to a list.
        OpportunityWrapper[] oppyList = new List<OpportunityWrapper>();
        Date closeDate = Date.today().addDays(10);
        oppyList.add( new OpportunityWrapper(new Opportunity(
            Name='Edge Installation',
        oppyList.add( new OpportunityWrapper(new Opportunity(
            Name='United Oil Installations',
            StageName='Needs Analysis',
        oppyList.add( new OpportunityWrapper(new Opportunity(
            Name='Grand Hotels SLA',

        // Sort the wrapper objects using the implementation of the 
        // compareTo method.

        // Verify the sort order
        System.assertEquals('Grand Hotels SLA', oppyList[0].oppy.Name);
        System.assertEquals(25000, oppyList[0].oppy.Amount);
        System.assertEquals('Edge Installation', oppyList[1].oppy.Name);
        System.assertEquals(50000, oppyList[1].oppy.Amount);
        System.assertEquals('United Oil Installations', oppyList[2].oppy.Name);
        System.assertEquals(100000, oppyList[2].oppy.Amount);

        // Write the sorted list contents to the debug log.
  • Your implementation could certainly be more concise, but the bigger issue with your code is that it will throw a NullPointerException if any record's Amount field is null (and OP wanted to sort on a Date field` anyway...).
    – Adrian Larson
    Dec 27, 2016 at 14:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .