Thursday, 9 June 2022

Collections in Salesforce

 

SET:

A set is a collection of unique, unordered elements. It can contain primitive data types(String, Integer, Date, etc) or sObjects. If you need ordered elements use a List instead. You typically see Sets used to store collections of IDs that you want to use in a SOQL query.

Basics syntax:

Set<datatype> set_name = new Set<datatype> ();

Set<datatype> set_name = new Set<datatype> {value1, value2. . .] };

Examples:

Set<String> s = new Set<String> ();

Set<String> s = new Set<String> {'Jon', 'Quinton', 'Reid'};

As mentioned before one of the main characteristics of a Set is the uniqueness of elements. You can safely try to add the same element (e.g., 100, 'c', 125.25) to a Set more than once and it will just disregard the duplicate (without throwing an Exception). However, there is a slight twist when dealing with sObjects. Uniqueness of sObjects is determined by comparing fields in the objects. The following code will result in only one element in the Set.

 

Account acct1 = new account (Name='ACME Corp');

Account acct2 = new account (Name='ACME Corp');

Set<Account> s = new Set<Account> {acct1, acct2}; // Set will only contain 1 element

Different field values cause the objects to become unique.

Account acct1 = new account (Name='ACME Corp', BillingAddress='100 Main');

Account acct2 = new account (Name='ACME Corp');

Set<Account> s = new Set<Account>{acct1, acct2}; // Set will only contain 2 elements

 Set Methods

 There are a number Set methods so check out the docs for a complete list, but here are some of the more common ones you might use.

// create a new set with 3 elements

Set<String> s = new Set<String>{'Jon', 'Quinton', 'Reid'};

// adds an element IF not already present

s.add('Sandeep');

// return the number of elements

System.debug('=== number of elements: ' + s.size());

DEBUG|=== number of elements: 4

// removes the element if present

s.remove('Reid');

 // return the number of elements

System.debug('=== number of elements: ' + s.size());

DEBUG|=== number of elements: 3

// returns true if the set contains the specified element

System.debug('=== set contains element Jon: ' + s.contains('Jon'));

DEBUG|=== set contains element Jon: true

// output all elements in the set

for (String str : s)

  // outputs an element

  System.debug('=== element : ' + str);

DEBUG|=== element : Jon

DEBUG|=== element : Quinton

DEBUG|=== element : Sandeep

 

// makes a duplicate of the set

Set<String> s1 = s.clone();

// displays the contents of the set

System.debug('=== contents of s1: ' + s1);

DEBUG|=== contents of s1: {Jon, Quinton, Sandeep}

 // removes all elements

s1.clear();

 

// returns true if the set has zero elements

System.debug('=== is the s1 set empty? ' + s1.isEmpty());

DEBUG|=== is the s1 set empty? true

most of the time, we construct a Set of IDs from a query, trigger context, etc. and then use it as part of the WHERE clause in their SOQL query:

 Set<ID> ids = new Set<ID>{'0017000000cBlbwAAC','0017000000cBXCWAA4'};

List<Account> accounts = [Select Name From Account Where Id = :ids];

 

LISTS:

Lists are the mostly widely used collection so learn to love them (I do!!). A List is a collection of primitives, user-defined objects, sObjects, Apex objects or other collections (can be multidimensional up to 5 levels). Use a List (as opposed to a Set) when the sequence of elements is important. You can also have duplicate elements in a List. List are zero-based so the first element in the List is always 0.

The basic syntax for creating a new List is:

 List <datatype> list_name = new List<datatype>();]

List <datatype> list_name = new List<datatype>{value1, value2. . .]};

Examples:

 List<Integer> s = new List<Integer>();

List<String> s = new List<String>{'Hello', 'Quinton', 'Reid'};

 

// Create a nested List of Sets

List<List<Set<String>>> s2 = new List<List<Set<String>>>();

 

// Create a List of contact records from a SOQL query

List<Contacts> contacts = [SELECT Id, FirstName, LastName  FROM Contact LIMIT 10];

 

Lists and Arrays are pretty much interchangeable and you can mix and match them:

 

List<Contact> contacts = newContact[] {new(), newContact()};

List<String> s = new List<String>{'Hello', 'Quinton', 'Reid'};

String[] s1 = new String[]{'Hello', 'Quinton', 'Reid'};

System.debug('=== ' + s.get(0));                // DEBUG|=== Hello

System.debug('=== ' + s1.get(0));              //DEBUG|=== Hello

System.debug('=== ' + s[0]);                     //DEBUG|=== Hello

System.debug('=== ' + s1[0]);                    //DEBUG|=== Hello

 

List Methods:

There are a number List methods so check out the docs for a complete list, but here are some of the more common ones you might use.

 List<String> s = new List<String>{'Jon', 'Quinton', 'Reid'};

 

// adds an element

s.add('Sandeep');

 

// adds an element

s.add('Sandeep');

 

// return the number of elements

System.debug('=== number of elements: ' + s.size());

DEBUG|=== number of elements: 5

 

// displays the first element

System.debug('=== first element: ' + s.get(0));

DEBUG|=== first element: Hello

 

// removes the first element

s.remove(0);

 

// return the number of elements

System.debug('=== number of elements: ' + s.size());

DEBUG|=== number of elements: 4

 

// makes a duplicate of the set

List<String> s1 = s.clone();

 

// displays the contents of the set

System.debug('=== contents of s1: ' + s1);

DEBUG|=== contents of s1: (Quinton, Reid, Sandeep, Sandeep)

 

// replace the last instance of 'Sandeep' with 'Pat'

s1.set(3,'Pat'); // displays the contents of the set

System.debug('=== contents of s1: ' + s1);

DEBUG|=== contents of s1: (Quinton, Reid, Sandeep, Pat)

 

// sorts the items in ascending (primitive only)

s1.sort();

 

// displays the contents of the set

System.debug('=== sorted contents of s1: ' + s1);

DEBUG|=== sorted contents of s1: (Pat, Quinton, Reid, Sandeep)

// removes all elements

s.clear();

 

// returns true if the set has zero elements

System.debug('=== is the list empty? ' + s.isEmpty());

DEBUG|=== is the list empty? true

 

 You can use a List of Strings in the same sort of way you would a Set as part of a SOQL query:

 

List<String> ids = new List<String>{'0017000000cBlbwAAC','0017000000cBXCWAA4'};

List<Account> accounts = [Select Name From Account Where Id IN :ids];

Since SOQL queries return Lists of records, you can use them directly for iteration:

 

for (Account a : [Select Id, Name From Account Limit 2]) {

System.debug('=== ' + a.Name);

}

You can also use the List in a traditional for loop:

 List<Account> accounts = [Select Id, Name From Account Limit 2];

for (Integer i=0;i<accounts.size();i++) {

System.debug('=== ' + accounts.get(i).Name);

}

 

MAP :

A Map is a collection of key-value pairs. Keys can be any primitive data type while values can include primitives, Apex objects, sObjects and other collections. Use a map when you want to quickly find something by a key. Each key must be unique but you can have duplicate values in your Map.

 The basic syntax for creating a new Map is:

Map<key_datatype, value_datatype> map_name = new map<key_datatype, value_datatype>();

 

Map<key_datatype, value_datatype> map_name = new map<key_datatype, value_datatype>{key1_value =>  value1_value [, key2_value =>  value2_value. . .]};

Examples:

Map<Integer, String> m = new Map<Integer, String>{5 => 'Jon', 6 => 'Quinton', 1 => 'Reid'};

Map<ID, Set<String>> m = new Map<D, Set<String>>();

// creates a map where the key is the ID of the record

Map<Id, Account> aMap = new Map<Id, Account>([Select Id, Name From Account LIMIT 2]);

Map Methods : 

There are a number Map methods so check out the docs for a complete list, but here are some of the more common ones you might use.

Map m = new Map{5 => 'Jon', 6 => 'Quinton', 1 => 'Reid'};

// displays all keys

System.debug('=== all keys in the map: ' + m.keySet());

DEBUG|=== all keys in the map: {1, 5, 6}

 

// displays all values

System.debug('=== all values in the map (as a List): ' + m.values());

DEBUG|=== all values in the map (as a List): (Reid, Jon, Quinton)

 

// does the key exist?

System.debug('=== does key 6 exist?: ' + m.containsKey(6));

DEBUG|=== does key 6 exist?: true

 

// fetches the value for the key

System.debug('=== value for key 6: ' + m.get(6));

DEBUG|=== value for key 6: Quinton


// adds a new key/value pair

m.put(3,'Dave');

// returns the number of elements

System.debug('=== size after adding Dave: ' + m.size());

DEBUG|=== size after adding Dave: 4

 

// removes an element

m.remove(5);

System.debug('=== size after removing Jon: ' + m.size());

DEBUG|=== size after removing Jon: 3

 

// clones the map

Map m1 = m.clone();

System.debug('=== cloned m1: ' + m1);

DEBUG|=== cloned m1: {1=Reid, 3=Dave, 6=Quinton}

 

// removes all elements

m.clear();


// returns true if zero elements

System.debug('=== is m empty? ' + m.isEmpty());

DEBUG|=== is m empty? true

Maps are used very frequently to store records that you want to process or as containers for "lookup" data. It's very common to query for records and store them in a Map so that you can "do something" with them. The query below creates a Map for you where the key is the ID of the record. This makes it easy to find the record in the Map based upon the ID.

 Map<Id,Account> accountMap = new Map<Id, Account>(

  [Select Id, Name From Account LIMIT 2]);

System.debug('=== ' + accountMap);

 

// keySet() returns a Set we can iterate through

for (Id id : accountMap.keySet()) {

  System.debug('=== ' + accountMap.get(id).Name);

}

You'll use Maps quite a bit when writing triggers. For before update and after update triggers there are two trigger context variables named oldMap and newMap. The oldMap contains a list of sObject before they were modified. The newMap contains a list of sObject with the updated values. You typically use these Maps to make some sort of comparison inside the trigger:

 

for (Id id : Trigger.newMap.keySet()) {

  if (Trigger.oldMap.get(id).LastName != Trigger.newMap.get(id).LastName) {

    System.debug('=== the last name has changed!!');

    // handle the name change somehow  

  }

}

 

Convert list to Map of id as key and value as list<sobjects>

List<Contact>listcontacts = [Select id, name, Accountid, Phone from Contact];

Map<Id, list<contact>MapAcc = new Map<Id, list<contact>();

For(contact c: listcontacts){

   If(MapAcc.containkey(c.Accountid)){

      List<contact>oldcon = MapAcc.get(c.Accountid);

      Oldcon.add(c);

      MapAcc .put(c.Accountid,oldcon);

   }

   Else {

            List<contact>newcon = new list<contact>();

            Newcon.add(c);

            MapAcc.put(c.Accountid,newcon);

            }

}

Converting from a List to Set:

List<String> lStrings = new List<String>{'a','b','c','d','e'};

Set<String> sStrings = new Set<String>(lStrings);

 

Converting from a Set to a List

Set<String> sStrings = new Set<String>{'a','b','c','d','e'};

 List<String> lStrings = new List<String>(sStrings);

 

Converting list to Map with id as key and value as sobject

 

List<Lead> leadList = [SELECT Id, Name FROM Lead];

 

Map<Id, Lead> leadMap = new Map<Id, Lead>([SELECT Id, Name FROM Lead]);

 

Or,

Map<Id, Lead> mapFromList = new Map<Id, Lead>(leadList);

 

 

 

 

 

No comments:

Post a Comment

Duplicate id in list

  Error 'System.ListException: Duplicate id in list' in Apex : list  can hold  duplicate values, but if you try to add duplicate  sO...