Skip to content
Home » Blog Archive » Beginner’s Guide to Salesforce Apex: An Introduction to Collections – Lists, Sets, and Maps

Beginner’s Guide to Salesforce Apex: An Introduction to Collections – Lists, Sets, and Maps

Welcome, coding crew! In this post, I’ll be discussing one of the most powerful features of Salesforce programming: Collections. As you may know, collections are used to store groups of related data & they come in three flavours: Lists, Sets, and Maps. Throughout this post, I’ll be providing an introduction to these collections and their types in Salesforce Apex. Whether you’re new to programming in Salesforce or looking to expand your knowledge, you’re in the right place! Don’t worry if you’re not familiar with collections yet – I’m here to guide you through. Before we dive in, I recommend checking out my previous blog post, ‘Beginner’s Guide to Salesforce: Primitive Data Types and Methods‘, which covers variables and primitive data types. It’s a great foundation for understanding collections in Salesforce Apex.

If you are new to Salesforce development world, I would recommend that you start with this post first “Essential Salesforce Developer Vocabulary for Beginners

Lists: The First Collection Type in Salesforce Apex

An Apex List is a collection of multiple items, much like a to-do list where you can add new tasks, remove completed ones, and prioritize the order in which you want to complete them. The order of items in the List is important and can be changed by rearranging them.

This image shows the first Salesforce Apex collection type: List. It is represented as an indexed array with elements organized sequentially.

Each item in an Apex List has a unique Index, which can be thought of as its address. This makes it easy to retrieve a specific item from the List by using its Index as a reference point. In contrast to Sets, Lists maintain the order of elements and enable duplicates.

Syntax

The below syntax is used to declare and initialize an empty List, adding items using the “add” method and retrieving an item from the List using the “get” method:

//Declaring and initializing an empty List
List<DataType> listName = new List<DataType>();

//Adding items to the list
listName.add(ValueSameDataType);

//Retrieving Items from the list
DataType variableName = listName.get(ItemIndex);
  • List<DataType>: indicates the type of List you are creating.
  • DataType: specifies the data type of the elements that the List can hold.
  • listName: is the name you give to the List variable. This is how you refer to the List later in your code.
  • new List(): is a constructor that creates a new instance of the List.
  • add(): a built in method used to add items to the List.
  • ValueSameDataType: Value matching the DataType of the List.
  • variableName: is a variable of the same List DataType that will hold the value we are trying to retrieve from the list.
  • get(): Built in method used to get item from the list using its index. We start counting the item index from 0.
  • ItemIndex: This is an integer value for the item’s index we want to retrieve. For instance, in the previously mentioned list, “Drink Coffee” can be found at index 4.

Alternatively, you can initialize a List with values in a single statement:

List<DataType> listName = new List<DataType>{value1, value2, value3, value4};

value1, value2, value3, and value4 are values of the same data type as specified in DataType.

Let’s see the below examples:

//empty String list
List<String> lstDayNames= new List<String>(); 
lstDayNames.add('Monday'); //add value to the list

//List of Strings with three values
List<String> lstMonthNames = new List<String>{'February','April','May','February'};
lstMonthNames.add('June'); //add extra month

//Empty list of Accounts
List<Account> lstAccounts = new List<Account>();

//List of Integers with 2 values in it
List<Integer> lstNumbers = new List<Integer>{2,3};
lstNumbers.add(11); //add extra Integer value

//Retrieving items from the lists we defined
System.debug('Check Day Name: '+ lstDayNames.get(0));
System.debug('Check Month Name: '+ lstMonthNames.get(2));
System.debug('Check Number Value: '+lstNumbers.get(1));
Screenshot of the Salesforce Developer Console displaying the output of a List, showcasing the elements and their corresponding index positions
Screenshot from developer console log.

Important List Methods

We talked about the two most common List methods, “add()” and “get()”, before. But there are plenty of other useful methods you can use with Lists! In this section, I’ll show you a few examples of these methods. But remember, if you want to learn more about all the List Methods, make sure to check out additional resources.

Method NameUsageExample
sort()Sorts the items in the list in
ascending order
List<Integer> lstScores=new List<Integer>{4,1,22,10};
System.debug(‘List Before Sorting: ‘+lstScores);
lstScores.sort();
System.debug(‘List After Sorting: ‘+lstScores);

Output in Developer Console:
List Before Sorting: (4, 1, 22, 10)
List After Sorting: (1, 4, 10, 22)
size()Returns the number of items
in the list
List<Integer> lstScores=new List<Integer>{4,1,22,10};
System.debug(‘List Size: ‘+lstScores.size());

Output in Developer Console:
List Size: 4
isEmpty()Returns true if the list is
empty, otherwise returns false
List<Integer> lstScores=new List<Integer>();
System.debug(‘Check if empty1: ‘+lstScores.isEmpty());
lstScores.add(4);
System.debug(‘Check if empty2: ‘+lstScores.isEmpty());

Output in Developer Console:
Check if empty1: true
Check if empty2: false
contains()Returns true if the list contains
the item I am looking for, otherwise returns false
List<Integer> lstScores=new List<Integer>{4,1,22,10};
System.debug(‘List Contains 4: ‘+lstScores.contains(4));
System.debug(‘List Contains 100: ‘+lstScores.contains(100));

Output in Developer Console:
List Contains 4: true
List Contains 100: false
Table of Sample List Methods

Iterating over a List

To iterate over a list in Salesforce, you can use a for loop, we will explain it further in a different post so stay Tuned!

Here’s an example:

//Initialize a list of String and values to it
List<String> lstFruitNames = new List<String>{'Orange', 'Watermelon', 'Cherry'};

//loop over the list of Strings for the fruit names 
for(String strFruitName : lstFruitNames){
    System.debug('Fruit Name: '+strFruitName);
}

The loop variable “strFruitName” is assigned to each item in the list, and we use the System.debug() method to output each string.

Screenshot of the Salesforce Developer Console showing the output from iterating over a List and printing the results, demonstrating the element-by-element processing
Screenshot from developer console log.

Sets: The Collection Type for Unique Values in Salesforce Apex

Sets are another type of collection in Salesforce that store a group of related data, just like Lists. However, the key difference is that sets don’t store data in any particular order, and they don’t allow duplicates.

Let’s compare sets to the receipt you will get after finishing your grocery shopping and scanning all your items in the shopping cart:

  • Imagine you are shopping for groceries and you put some items into your shopping cart.
  • Your shopping cart can have duplicates, for example, you might buy two cans of the same brand of soup.
  • When you check out, the cashier will only scan each item once even the duplicates
  • The receipt will show each item only once, regardless of how many duplicates there were in your shopping cart.

This is similar to how sets work – each item appears only once in the set, even if you add duplicates.

Image of a shopping cart filled with various items, representing a real-life example of a Set in Salesforce Apex, with unique elements to be extracted
Image of a receipt displaying the unique items purchased from the shopping cart, symbolizing the concept of Sets in Salesforce Apex as a collection of distinct elements

The Set representing the items in the receipt above would be:

//Define Item Set as Set of String 
Set<String> setItems = new Set<String>{'Cheese','Chicken Soup','Pizza','Bread','Chicken'};

Syntax

The following syntax is used to declare and initialize an empty Set and add items using the ‘add’ method. We cannot retrieve an item using an index as we did with a List because Sets are not ordered, and each item does not have an index (address).

Set<DataType> setName = new Set<DataType>(); //initializing an empty set
setName.add(ValueSameDataType); //adding items in the set
  • Set<DataType>: indicates the type of Set you are creating.
  • DataType: specifies the data type of the elements that the Set can hold.
  • setName: is the name you give to the Set variable. This is how you refer to the Set later in your code.
  • new Set(): is a constructor that creates a new instance of the Set.
  • ValueSameDataType: Value matching the DataType of the Set.

Alternatively, you can initialize a Set with values in a single statement as we did in the above example for the receipt:

//Initializing a set and add to it four values in the same line of code
Set<DataType> setName = new Set<DataType>{value1, value2, value3, value4};

value1, value2, value3, and value4 are values of the same data type as specified in DataType.

Let’s see the below examples:

Set<String> setWeekDays = new Set<String>(); //Declare and initialize an empty Set 
setWeekDays.add('Monday'); //add values to the set 
setWeekDays.add('Monday'); //add duplicate value to the set (No error and it would be ignored)
setWeekDays.add('Tuesday'); //add values to the set 
System.debug('Check Days : '+setWeekDays);

//Declare and initialize a set of integers
Set<Integer> setScores = new Set<Integer>{33,27,21,25};
System.debug('Check Scores : '+setScores);
Screenshot of the Salesforce Developer Console displaying the output of a Set, showcasing the unique and unordered elements within the collection
Screenshot from developer console log.

Important Set Methods

We checked briefly while learning the Sets syntax the most important method that you would use frequently “add()”. There is other methods that you can use with Set, I will cover a sample here but check the resources to learn more about other Set Methods.

Method NameUsageExample
contains()Returns true if the Set
contains the item I am
looking for, otherwise
returns false
Set<Integer> setScores=new Set<Integer>{20,11,9};
System.debug(‘Set Contains 25: ‘+setScores.contains(25));
System.debug(‘Set Contains 11: ‘+setScores.contains(11));

Output in Developer Console:
Set Contains 25: false
Set Contains 11: true
isEmpty()Returns true is Set is
Empty, Otherwise
return false.
Set<Integer> setScores=new Set<Integer>();
System.debug(‘Check isEmpty1 : ‘+setScores.isEmpty());
setScores.add(21);
System.debug(‘Check isEmpty2 : ‘+setScores.isEmpty());

Output in Developer Console:
Check isEmpty1 : true
Check isEmpty2 : false
size()Returns the number
of items in the set.
Set<Integer> setScores=new Set<Integer>{20,11,19};
System.debug(‘Check Set Size1: ‘ +setScores.size());

//Add duplicate Value
setScores.add(20);
System.debug(‘Check Set Size2: ‘ +setScores.size());

//Add a new value to the Set
setScores.add(25);
System.debug(‘Check Set Size3: ‘ +setScores.size());

Output in Developer Console:
Check Set Size1: 3
Check Set Size2: 3
Check Set Size3: 4

Note: Adding a duplicate item in the set didn’t throw an error
but it didn’t add it to the set and that is why the size1 and size2
are the same
addAll(fromList)This method will add
the List elements
into the Set if they
don’t already exist.

The method will update
your Set and it will return
true if it was modified.
Set<String> setUniqueValues = new Set<String>();

List<String> lstValues1 = new List<String>();
lstValues1.add(‘Sally’);
lstValues1.add(‘Testing’);

List<String> lstValues2 = new List<String>();
lstValues2.add(‘Checking’);
lstValues2.add(‘Sally’);

List<String> lstValues3 = new List<String>();
lstValues3.add(‘Checking’);
lstValues3.add(‘Sally’);

Boolean isUpdated1=setUniqueValues.addAll(lstValues1);
Boolean isUpdated2=setUniqueValues.addAll(lstValues2);
Boolean isUpdated3=setUniqueValues.addAll(lstValues3);

System.debug(‘Check isUpdated1 : ‘+isUpdated1);
System.debug(‘Check isUpdated2 : ‘+isUpdated2);
System.debug(‘Check isUpdated3 : ‘+isUpdated3);
System.debug(‘Check setUniqueValues : ‘+setUniqueValues);

Output in Developer Console:
Check isUpdated1 : true
Check isUpdated2 : true
Check isUpdated3 : false
Check setUniqueValues : {Checking, Sally, Testing}
Table of Sample List Methods

Iterating over a Set

To iterate over a Set in Salesforce, you can use a for loop, we will explain it further in a different post so stay Tuned!

Here’s an example:

//Initialize a Set of String and values to it
Set<String> setFruitNames = new Set<String>{'Orange', 'Watermelon', 'Cherry'};

//loop over the Set of Strings for the fruit names 
for(String strFruitName : setFruitNames){
    System.debug('Fruit Name Set Example: '+strFruitName);
}

The loop variable “strFruitName” is assigned to each item in the Set, and we use the System.debug() method to output each string.

Screenshot of the Salesforce Developer Console showing the output from iterating over a Set and printing the results, illustrating the unordered processing of distinct elements
Screenshot from developer console log.

Maps: The Collection Type for Key-Value Pairs in Salesforce Apex

Maps are another type of collections in Salesforce that store a group of related data. Like Lists and Sets, Maps allow you to store and manipulate data, but with some unique features.

The main difference between Maps and other collection types is that maps store data as key-value pairs. This means that you can associate a value with a specific key, and then use that key to retrieve the corresponding value later on.

Let’s use the receipt we got from the grocery store we discussed above while talking about Sets to understand the different use case of Maps.

Image of a receipt displaying items and their respective quantities purchased, representing the concept of Maps in Salesforce Apex as a collection of key-value pairs

We saw how we used Set to get the list of items we bought, what if we want get the items we bought and their corresponding quantities? We can’t achieve that with Set but we can with the Map because it stores key-value pairs as below:

Map<String,Integer> mapItemsQuantity = new Map<String,Integer>();
mapItemsQuantity.put('Cheese',1);
mapItemsQuantity.put('Chicken Soup',3);
mapItemsQuantity.put('Pizza',2);
mapItemsQuantity.put('Bread',1);
mapItemsQuantity.put('Chicken',1);

Syntax

The following syntax is used to declare and initialize an empty Map, add items using the ‘put‘ method and getting a specific Item using the key value of the key-value pair and the ‘get‘ method.

//Initialize an empty map and specifying its key data type and value data type
Map<DataTypeOfKey, DataTypeOfValue> mapName = new Map<DataTypeOfKey, DataTypeOfValue>();

//syntax to put key-value pairs in the map
mapName.put(keySameType,ValueSameType); 

//retrieve a value from the map using its key
DataTypeOfValue retrievedValue = mapName.get(KeyValue);
  • Map<DataTypeOfKey,DataTypeOfValue>: indicates the Data type for the key and the data type for value.
  • mapName: is the name you give to the Map variable. This is how you refer to the Map later in your code.
  • new Map(): is a constructor that creates a new instance of the Map, it will be an empty map.
  • put(): Method used to add a key-value pair in the map.
  • retrievedValue: Variable name of the same data type used with the value.
  • get(): Method used to get a specific value from the map using its key value.

Alternatively, you can initialize a Map with values in a single statement as below:

Map<DataTypeOfKey, DataTypeOfValue> myMap = new Map<DataTypeOfKey, DataTypeOfValue>{
                                                  Key1 => Value1, 
                                                  Key2 => Value2};

Let’s see the below examples:

//Initialize an empty map with Key as String and value as number
Map<String,Integer> mapStudentScores=new Map<String,Integer>();

//Add key pair values
mapStudentScores.put('Sally',22);
mapStudentScores.put('Sarah',30);
mapStudentScores.put('Emilia',27);

//Test Getting the score of Sarah
System.debug('Sarah Score: '+mapStudentScores.get('Sarah'));

//Declare and Initialize a map and add key-value pairs at same line
Map<String,Integer> mapStudentAge=new Map<String,Integer>{
                                          'Daniel'=>12,
                                          'Andrew'=>11,
                                          'Mark'=>13};

//Test Getting the Age of Mark and printing it
System.debug('Mark Age: '+mapStudentAge.get('Mark'));
Screenshot of the Salesforce Developer Console displaying the output of a Map, showcasing the key-value pairs representing items and their respective values
Screenshot from developer console log.

Map’s keys are unique so if you try to add same key more than once with different values, the last value will be the once stores.

/* declare and initialize the map where the day String value is the key and temperature
  Integer is the value */
Map<String,Integer> mapDaysTemperature = new Map<String,Integer>();
mapDaysTemperature.put('Monday',13);
mapDaysTemperature.put('Tuesday',15); 
mapDaysTemperature.put('Tuesday',30); //this is duplicate

System.debug('Tuesday Temperature : '+mapDaysTemperature.get('Tuesday'));
Screenshot of the Salesforce Developer Console displaying the output of a Map, with a key-value pair for an item and its quantity, showcasing that the last value for a duplicate key overwrites the previous value in a Map
Screenshot from developer console log.

Important Map Methods

We checked briefly while learning the Maps syntax two important methods that you would use frequently “put()” and “get()”. There is other methods that you can use with Maps, I will cover a sample here but check the resources to learn more about other Map Methods.

Method NameUsageExample
keySet()Used to return a Set
of all the Key values of
the Map
Map<String,Integer> mapItems=new Map<String,Integer>();
mapItems.put(‘Cheese’,1);
mapItems.put(‘Chicken Soup’,3);
mapItems.put(‘Pizza’,2);
System.debug(‘Check Map Keys: ‘+mapItems.keySet());

Output in Developer Console:
Check Map Keys: {Cheese, Chicken Soup, Pizza}
values()Used to return a List of the
values of the Map
Map<String,Integer> mapItems=new Map<String,Integer>();
mapItems.put(‘Cheese’,1);
mapItems.put(‘Chicken Soup’,3);
mapItems.put(‘Pizza’,2);
mapItems.put(‘Butter’,2);
System.debug(‘Check Map Values: ‘+mapItems.values());

Output in Developer Console:
Check Map Values: (1, 3, 2, 2)
isEmpty()Returns true is Map is
Empty, Otherwise
return false.
Map<String,Integer> mapItems=new Map<String,Integer>();
System.debug(‘Check isEmpty1: ‘+mapItems.isEmpty());
mapItems.put(‘Cheese’,1);
System.debug(‘Check isEmpty2: ‘+mapItems.isEmpty());

Output in Developer Console:
Check isEmpty1: true
Check isEmpty2: false
size()Returns the number of
key-value pairs in the set.
Map<String,Integer> mapItems=new Map<String,Integer>();
System.debug(‘Check size1: ‘+mapItems.size());
mapItems.put(‘Cheese’,1);
mapItems.put(‘Butter’,2);
System.debug(‘Check size2: ‘+mapItems.size());

Output in Developer Console:
Check size1: 0
Check size2: 2
containsKey(key)Returns true if the map
contains a key-value pair
with the key we are looking for
Map<String,Integer> mapItems=new Map<String,Integer>();
mapItems.put(‘Cheese’,1);
mapItems.put(‘Butter’,2);
System.debug(‘Check1: ‘+mapItems.containsKey(‘Cheese’));
System.debug(‘Check2: ‘+mapItems.containsKey(‘Milk’));

Output in Developer Console:
Check1: true
Check2: false
Table of Sample Map Methods

Iterating over a Map

In Salesforce, you can use a for loop to loop through a Set. We will explain this in more detail in a future post, so keep an eye out for that!

When it comes to iterating over a Map in Salesforce, it contains key-value pairs. There are two ways to loop through the values in a Map.

  1. One way is to iterate over the keys and then use the ‘get’ method to retrieve the value associated with each key.
  2. The other way is to directly iterate over the values, without considering the keys and their association with the values.

Here’s an example:

/* declare and initialize the map where the day String value is the key and temperature
  Integer is the value */
Map<String,Integer> mapDaysTemperature = new Map<String,Integer>();
mapDaysTemperature.put('Monday',13);
mapDaysTemperature.put('Tuesday',15); 
mapDaysTemperature.put('Wednesday',30); 

//First loop through the keys 
System.debug('====First loop through the keys Result======');
for(String strDayName : mapDaysTemperature.keySet()){
    //Print the Key and its value
    System.debug('Day: '+strDayName+' temperatire is : '+mapDaysTemperature.get(strDayName));
}

System.debug('====Secong loop through the Values ======');
//Second loop through the values 
for(Integer temperatureValue :  mapDaysTemperature.values()){
    //Print the value
    System.debug('Temperature : '+temperatureValue);
}
Screenshot of the Salesforce Developer Console displaying the output of iterating over the keys of a Map and getting the corresponding values, followed by iterating over the values and printing each value, showcasing the processing of a Map's key-value pairs
Screenshot from developer console log.

Conclusion

Understanding the differences between Lists, Maps, and Sets is critical when developing in Salesforce. These collections are powerful tools that can help you store, manipulate, and retrieve data efficiently.

Choosing the appropriate data structure for your use case is critical to ensure efficient and optimized code. Using the wrong data structure can impact your code quality and performance.

Lists are ordered collections of elements that can contain duplicates. They are useful when you need to store data in a particular order and access it using an index. Maps, on the other hand, are collections of key-value pairs that allow you to access data based on a specific key. They are ideal for storing data that needs to be looked up frequently. Sets, meanwhile, are collections of unique elements that are unordered. They are useful when you need to keep track of distinct values and perform set operations.

Here is a comparison table of Lists, Maps, and Sets in Salesforce:

ListSetMap
OrderingOrderedUnorderedUnordered
Duplicates allowedYesNo– Keys : No
– Values: Yes
Retrieval by indexYesNoNo
Retrieval by keyNoYesYes
Contains Key-value Pairs?NoNoYes
Adding New Itemsadd methodadd methodput method
Use Cases– Ordered collection
– Sorting
– Retrieving elements by index
– Storing SOQL statement result (We will cover SOQL in another post)
– Removing duplicates
– Keeping track of a unique set of values for a particular field, such as a set of unique email addresses for a list of contacts.
– Key-value storage, such as storing the account ID as the key and the account name as the value.
– Efficient lookup by key, such as a map of product codes and their corresponding prices.
– Efficiently accessing related data, such as a map of contact IDs and their corresponding account IDs for easy lookup of related accounts.
Comparison table of Salesforce Collections: Lists, Sets, and Maps, highlighting their similarities and differences.

Resources

Join the conversation

Your email address will not be published. Required fields are marked *