+ Start a Discussion
Archana BattaArchana Batta 

Difference between List and Map

Hi,

Can someone help me in understanding the difference between below mentioned two statements. You can see that its the same SOQL query being used in both the statements. But it's the collection to store the SOQL results that differs. How does List and Map behave in these two statements?

List<Account> acctsWithOpps = [SELECT Id,(SELECT Id,Name FROM Opportunities) FROM Account WHERE Id IN :Trigger.New];

AND

Map<Id, Account> AcctWithOpps = new Map<Id, Account>([SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE ID IN:Trigger.New]);

Thanks & Regards,
B Archana
Lokesh KumarLokesh Kumar
HI Archna,

I Hope you are doing great!

PFB my understanding.

The list, set,map is called collections in Apex:

List: A list is an ordered collection
so use list when you want to identify list element based on Index Number.(List can contain Duplicates)
EX: List<Account> accList = new List<Account>();

Set: A set is an unordered collection of primitives or sObjects that do not contain any duplicate elements.
So, use set if you want to make sure that your collection should not contain Duplicates.
EX: Set<Account> accSet = new Set<Account>()

Map: A map is a collection of key-value pairs where each unique key maps to a single value. Keys can be any primitive data type, while values can be a primitive, sObject, collection type or an Apex object.
EX: Map<Id, Account> accMap = new Map<Id, Account>();

There is a realtime situation where-in we need to loop through the collection of records and get the appropriate value from the matching record.

Requirement is:
      Using trigger populate the Account Type on the Contact record (only insert scenario).

To achieve this requirement, here I am mentioning using
trigger, so planning to write a trigger:

If we use List and not Map

 
trigger ContactTriggerWithList on Contact (before insert) {
    // Here taking the Set because we don't need to maintain duplicate
    Set<Id> accIdSet = new Set<Id>();
    
    for(Contact con: Trigger.new) {
        if(con.AccountId != null) {
            accIdSet.add(con.AccountId);
        }
    }
    
    if(!accIdSet.isEmpty()) {
        List<Account> accList = [Select Id, Name, Type from Account where Id IN: accIdSet];
        
        for(Contact con: Trigger.new) {
            if(con.AccountId != null) {
                for(Account acc: accList) {
                    if(con.AccountId == acc.Id) {
                        con.Acc_Type__c = acc.Type;
                    }
                }
            }
        }
    }
}

Same Trigger using the Map:
trigger ContactTriggerWithMap on Contact (before insert) {
    // Here taking the Set because we don't need to maintain duplicate
    Set<Id> accIdSet = new Set<Id>();
    
    for(Contact con: Trigger.new) {
        if(con.AccountId != null) {
            accIdSet.add(con.AccountId);
        }
    }
    
    if(!accIdSet.isEmpty()) {
        Map<Id, Account> accMap = new Map<Id, Account>([Select Id, Name, Type from Account where Id IN: accIdSet]);
        
        for(Contact con: Trigger.new) {
            if(con.AccountId != null) {
                con.Acc_Type__c = accMap.get(con.AccountId).Type;
            }
        }
    }
}

If you compare both the triggers,

Trigger 1 is having a List of Accounts, where in we have to loop through the matching Account every time to populate the Acc_Type in the second for loop.

Trigger 2 is having a Map of Accounts with Id and Account as the Datatypes. Hence we can directly get the corresponding Account record and populate the Acc_Type easily.

Hope this will clear you actual doubt.

Please do let me know if it helps you.

Regards,
Lokesh !!
NagendraNagendra (Salesforce Developers) 
Hi Archana,

May I suggest you to please check with the following blog spot which might help you to accelerate further with above requirement. Hope this helps.

Regards,
Nagendra.
 
Akshay_DhimanAkshay_Dhiman
Hi Archana,
 
List:
  1.  List is a collection of elements, Such as primitive data types (String, Integer, Date, etc), user defined objects, sObjects, Apex objects or other  collections (can be multidimensional up to 5 levels).
  2.  It allows duplicate valuesand  index position starts from zero.
 Map:

 Map is a collection of key-value pair.
 Keys can be any primitive data types (String, Integer, Date, etc) while values can include primitives, Apex objects, sObjects and other  collections.
 It allows duplicate values, but each key must be unique.
 So, List can store same object or record more than one time. but in Map, key always be unique so you can store dublicate objectes as a value in  map but you need to give different Keys each time.  
 Let me know if this helps you.

Regards,
 Akshay
Tolga SunarTolga Sunar
If you use a List, you'll get a List collection that consists of queried SObjects which you used in the "FROM" clause.

If you use a Map, you'll get a Map collection that consists of queried SObjects IDs as the key set and SObjects as the value set. In other words, the map elements will be "ID => SObject"

Using a map is generally more benefical for the developer, because:
  1. You can obtain the queried records' ID collection (as a Set) from map by: myMap.keySet();
  2. You can obtain the SObject list from map by: myMap.values();
David Roberts 4David Roberts 4
You can also use the keyset of the map to get the unique entries.
Populate the map with duplicates and the keyset extracts the unique keys (if your value pair is different, the get will get the last value).
This code can be run in the development console execute window: Note Blue deliberately has two values.

Map<String, String> colorCodes = new Map<String, String>();

colorCodes.put('Red', 'FF0000');
colorCodes.put('Blue', 'AAAAA0');
colorCodes.put('Green', '00FF00');
colorCodes.put('Blue', '0000FF');

Set <String> colorSet = new Set<String>();
colorSet = colorCodes.keySet();
system.debug(colorset);

system.debug('green? '+colorCodes.get('Green'));
system.debug('blue? '+colorCodes.get('Blue'));
system.debug('magenta? '+colorCodes.get('Magenta'));

for (string theStr : colorSet){
    system.debug(theStr+': '+colorCodes.get(theStr));
}
irfan alamirfan alam
Hi Lokesh Kumar,
I hope you are doing great!
Your above code worked for me perfectly.
However, I have written a code for the same job using for loop only, which is below.
Can you please confirm if there is any problem with my code????

trigger GetAccType on Contact (before insert) 
{
integer count=0;
list<account> a;
   for(contact c:trigger.new)
   {
     if(c.accountID!=null)
     {
       a=[select type from account where id=:(c.accountID)];
       c.account_type__C=a[count].type;
       count++;
            }
   }
}