Wednesday, December 7, 2016

Collections in Salesforce | When do we use List, Set, Map.

List, Set, Map are called collections in Apex.

List : 

A list is an ordered collection.

1) so use list when you want to identify list element based on Index Number.
2) list can contain Duplicates.

EX: List<Account> accList = new List<Account>();


Set :

A set is an unordered collection.

1) 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>();

Set<String> setString = new Set<String>();
// Add two strings to it
setString .add('item1');
setString .add('item2');


Map : 

A map is a collection of key-value pairs.

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>();


Map<Integer, String> mapOfString = new Map<Integer, String>();
mapOfString.put(1, 'string1');
mapOfString.put(2, 'string2');
System.assert(mapOfString.containsKey(1));
String value = mapOfString.get(2);
System.assertEquals('string2', value);
Set<Integer> s = mapOfString.keySet();


Map<String, String> myMap = new Map<String, String>{'a' => 'b', 'c' => 'd'};





Example 1:- 

Trigger to Populate the Account Field(Accunt Type) on the Contact record(In Type__C Custom Field)   (only insert scenario).


If we use List and not Map


Apex Trigger:


trigger ContactTriggerWithList on Contact (before insert){
Set<Id> SetAccountId = new Set<Id>(); // Use set to collect unique account ID
for(Contact con: Trigger.new){
if(con.AccountId != null){
SetAccountId.add(con.AccountId); // add Account in Set
}
}
if( SetAccountId.size() >0 ){
List<Account> listAccount = [ Select Id, Name, Type from Account where Id IN :SetAccountId ]; // Query Related Account
for(Contact con: Trigger.new) {
if(con.AccountId != null){
for(Account acc: listAccount){
if(con.AccountId == acc.Id){
con.Type__c = acc.Type;
}
}
}
}
}  
}


NOTE:- In this we are using List of Accounts, Where we have to loop through the matching Account every time to populate the Type__c in the second for loop. In this case need to use nested loop.


Instead of  Nested Loop We can use the Map.


Same Trigger using the Map:


trigger ContactTriggerWithMap on Contact (before insert){
    Set<Id> SetAccountId = new Set<Id>();
    for(Contact cont: Trigger.new) {
        if(cont.AccountId != null) {
            SetAccountId.add(cont.AccountId);
        }
    }
    
    if(SetAccountId.size() > 0 ) {
        Map<Id, Account> mapAccount = new Map<Id, Account>([Select Id, Name, Type from Account where Id IN :SetAccountId ]);
        for(Contact cont: Trigger.new){
            if(cont.AccountId != null && mapAccount.containsKey(cont.AccountId) ) {
                cont.Type__c = mapAccount.get(cont.AccountId).Type;
            }
        }
    }
}

NOTE:- Here we are using Map of Account so we can directly use the Map to get the Account record. No need of 2nd for loop here.


No comments:

Post a Comment