Maps in Salesforce


Maps are key-value pairs in any coding language



For me too using a Map was like pain and could never understand its real use. I used to code using list and set without using of a map where it was a must and which intern led to poor coding standards. But after lot of practice and understanding, i have figured out the simplest way to use a map in Salesforce. I would like to share it with you guys.


Syntax of a Map

Map<Key,Value> radicalMap = new Map<Key,Value>();

Key - Unique

Value - Not Unique



Example for a better understanding:

There is a box which contains sports equipment and its a mixture of 3 different sports. Sports like Hiking, Swimming and Cricket.Now the box contains a Cricket Bat, Hiking Gloves and Mittens, Duffle Bags, Pool Shoes, Ball, Cricket Pads, Bathrobes and Fleeces/Jumpers.
Now Radical Sports team would like to categorize them based on their particular sport.



Key               Value

Cricket           Cricket Bat
                      Ball
                      Cricket Pads
Hiking            Hiking Gloves and Mittens
                      Fleeces/Jumpers
                      Duffle Bags
Swimming     Pool Shoes
                      Bathrobes


If we try to sync the above categorization with our learning of the Map, the syntax would be as below -


Map<String,List<String>> spMap = new Map<String,List<String>>();

String = Key (Cricket,Hiking and Swimming)
List<String> = Values (Bat,Pool Shoes,...)

We have chosen a list of Strings because under each sport there is a bunch of equipments.

Example 1 with real use of Map :

  • We have Account which is the parent object and a contact associated with the account as the child Object. We are going to project the related Account,Contacts in a Visualforce page using an Apex Controller.
  • A Constructor in Controller to fetch the required data
  • Querying the list of Accounts
  • Querying the list of Contacts related to the above fetched Accounts
  • A Map to store Key(Account) and Values(list of Contacts)
  • Displaying Map on a Visualforce Page

 

Apex Class :

public class AccountMapClass
{
  public List<Account> acclist;
  public List<Contact> conList;
  public Map<String,List<String>> accConMap{get;set;}
  
  Public AccountMapClass()
  {
     acclist = [select id,name from Account];
     //Fetching the contacts related to above account list
     conList = [select id,lastName,accountId from contact 
                where AccountId in : acclist];
     
     //Initiating the Map
     accConMap = new Map<String,List<String>>();
     
     //First we search the contacts list over accounts fetched.
     //Iteration is done on AccountList
     for(account acc : acclist)
     {
         List<String> conlistInternal = new List<String>();
         //Iteration on Contact List
         for(contact con : conList)
         {
           //If we find any account id related to contact.AccountId
           //We are creating a list, adding the contact's LastName
             if(acc.id == con.accountId)
             {
                 conlistInternal.add(con.lastName);
             }             
         }
        //We put Key(AccountName),Values(list of Contacts) 
        accConMap.put(acc.name,conlistInternal); 
     }  
  }
}




VisualForce Page :

<apex:page controller="AccountMapClass">
  <apex:form >
      <apex:repeat value="{!accConMap}" var="m">
          <b>{!m}</b> -
          <apex:repeat value="{!accConMap[m]}" var="c">
              {!c} ,
          </apex:repeat><br/>
      </apex:repeat>
  </apex:form>
</apex:page>
OUTPUT :

Example 2 : 

An custom field added to Account Object - (Number of Contacts)
A trigger should be written for whenever a contact is created and lookup to account field is filled and saved. The Number of Contacts custom field(Number data type) on the Account should automatically updated with the contacts created.

Apex Trigger :


trigger updateNoOfContacts on Contact(after insert) 
{
  Map<String,List<string>> accConMap = new Map<String,List<string>>();
    Set<String> acc = new Set<String>();  
    for(Contact c : trigger.new)
    {
        acc.add(c.accountId);
    }
    for(String acct : acc)
    {
        List<String> contlist = new List<String>();
        for(Contact c : trigger.new)
        {
            if(acct == c.AccountId)
            contlist.add(c.id);   
        }
        accConMap.put(acct,contlist);   
    }
    List<Account> accObj = new List<Account>();
    for(account a : [select id,No_of_Contacts__c from account 
                     where id in : accConMap.KeySet()])
    {
        if(a.No_of_contacts__c>0){
        a.No_of_contacts__c  += (accConMap.get(a.id)).size();
        accObj.add(a);  
        }
        else
        {
             a.No_of_contacts__c  = 1;
             accObj.add(a);  
        }   
    }
    update accObj;
}

The code above is of a roll up summary field functionality (partially) while using a Lookup relationship instead of a Masterdetail relationship. Your assignment would be to write the same trigger on update and delete of contacts which would update the custom field on the accounts with its associated contacts.

Nested Map

Map in a Map is called a nested map.

Syntax :
Map<String,Map<String,List<String>>> mapOfMaps = new
Map<String,Map<String,List<String>>>();

Say for example, If each of Radical Team Member has an Account related to him and each Account has many contacts associated to it, like shown below :


In this case,  we would be iterating over Radical Team Member, in this loop create a map as created in the above examples and at the end of the loop add the key as key as Radical team member and its values be a map consisting of Account as the key of the inner map and list of contacts as values to the inner map which sounds good!!!

Code Snippet :

outerMap of<string,Map<string,List<string>>>
for(Radical Team Member)
{
     innerMap of <String,List<String>>
     for(Account)
     {
         New List of Contacts
         for(contact)
         {
               create list of contacts over iterated account
         }
          add key and values to innerMap
     }
    add key and values to outerMap
    outerMap.put(account,innerMap);
}

Thats it folks ! Your valuable feedback and comments are needed to enhance this post further.

Maps in Salesforce Maps in Salesforce Reviewed by dasfrogpractice on 04:08 Rating: 5

5 comments:

  1. Hi Sai,
    Very valuable information. Thanks for posting.

    I have one clarification.
    I guess, in No.of contacts example.

    else
    {
    a.No_of_contacts__c = accConMap.get(a.id)).size(); // a.No_of_contacts__c = 1;
    accObj.add(a);
    }


    Thanks,
    Kiran.

    ReplyDelete
    Replies
    1. Hi Kiran, thanks a ton!
      Regarding the size, they both mean the same. I have written the above for better understanding so that people can have two different lines of code in "if/else" statements... :)

      Delete
  2. hi guyz are you the same people having name as Radical technologies in pune or different?

    ReplyDelete
    Replies
    1. Nope.:) . We are a bunch of people sharing free Knowledge.

      Delete
  3. I acknowledge the author for his brilliant work for making this exceptionally useful and informative content to guide us.
    salesforce onilne forms

    ReplyDelete

Theme images by mariusFM77. Powered by Blogger.
Youtube Channel Image
Dasfrog Subscribe To watch more Salesforce Training
Subscribe