[SalesForce] How to sort keys in MAP while grouping

I am trying to insert list of wrapper class records in a MAP taking group name as KEY and related Wrapper class records as value pair .

the wrapper classes were

public class SCQLWrapperClass
{
   public date stDate{get;set;}
   public date endDate{get;set;}

   public String stDate1{get;set;}
   public String endDate1{get;set;}

    public double months{get;set;}
    public double quantty{get;set;}
    public double ppMonth{get;set;}
    public double discount{get;set;}
    public double netPrice{get;set;}        
    public double billTotal{get;set;}
    public String itmDesc{get;set;}        

}

public class groupingWrapClass
{
    public String yearname{get;set;}
    public Double billingtotal{get;set;}
    public Double pricepermonth{get;set;}
    public Double netpricepermonth{get;set;}        
    public List<SCQLWrapperClass> grpClsLst{get;set;}

    public groupingWrapClass(String yearname,Double pricepermonth,Double netpricepermonth,List<SCQLWrapperClass> grpClsLst)
    {
       this.yearname = yearname;
       this.pricepermonth = pricepermonth;
       this.netpricepermonth = netpricepermonth;
       this.grpClsLst = grpClsLst; 
    }

}

The Map was

Map map_lineitems_Group=new Map();

i was inserting values into the map taking keys from a sorted list as per user case.

the list contains group names { XYZ, ABC}

What ever the way i insert

map_lineitems_Group.put('XYZ', keyvalues);
map_lineitems_Group.put('ABC', keyvalues);

or in reverse way

map_lineitems_Group.put('ABC', keyvalues);
map_lineitems_Group.put('XYZ', keyvalues);

while iterating in VF page and debug logs too it is giving ABC as 1st group and XYZ as 2nd group. But i want it to be same order as in list. This list is a dynamic list, so i cannot predict the order too..

I have tried to loop over the map with a duplicate map , but results the same …

Is there any way to get the resulting map as desired…

Best Answer

Java has multiple map classes such as LinkedHashMap that preserve insertion order but Apex only has one map type which does not. So in Apex a work-around is to keep a separate list of the keys as lists preserve insertion order and get the keys to iterate through from the list:

private Map<string, groupingWrapClass> map_lineitems_Group
        = new Map<string, groupingWrapClass>();
private List<String> ordered_keys = new List<String>();

private void addToMap(String key, groupingWrapClass grouping) {
    map_lineitems_Group.put(key, grouping);
    ordered_keys.add(key);
}

private void xyz() {
    ...
    addToMap('XYZ', keyvalues);
    addToMap('ABC', keyvalues);
    ...
    // Run through the map keys in insertion order
    for (String key : ordered_keys) {
        groupingWrapClass grouping = map_lineitems_Group.get(key);
        ...
    }
}

PS

On exposing this to Visualforce, make both ordered_keys and map_lineitems_Group visible (add getters or make properties) and then e.g.:

<apex:pageBlockTable value="{!ordered_keys}" var="ordered_key">
<apex:column headerValue="Year Name" value="{!map_lineitems_Group[ordered_key].yearname}"/>
...
</apex:pageBlockTable>

as expressions in Visualforce use [] for map access.

You could also add an apex:variable to factor out the common map_lineitems_Group[ordered_key] expression.

Related Topic