The Apex Master Class

What Are Sets in Apex? (Apex Master Class Ep. 18)

3 min read

Subscribe on YouTube

What Is A Set?

A set is an unordered collection of elements that contains no duplicates.

Which is basically a List with both of its defining features removed. So why would you ever want that? Because those two “missing” features are exactly what makes sets useful.

Apex
Set<String> tacos = new Set<String>();

tacos.add('Crunchy');
tacos.add('Soft');
tacos.add('Crunchy');    //silently ignored. Already in there.

System.debug(tacos.size());   //2, not 3

Note it doesn’t error. It doesn’t warn you. It just quietly declines to add the duplicate and carries on. That’s the feature.


No Order Means No get()

Because a set is unordered, there’s no way to grab a specific element. There’s no get(), no square brackets, no index. There can’t be, because nothing has a position.

Apex
Set<String> tacos = new Set<String>{ 'Crunchy', 'Soft' };

//Neither of these exist. Don't bother.
//tacos.get(0);
//tacos[0];

What you can do is ask whether something’s in there, which is usually the actual question:

Code
tacos.contains('Soft');    //true
tacos.add('Breakfast');    //add one
tacos.remove('Crunchy');   //remove by value, not position
tacos.size();
tacos.isEmpty();
tacos.clear();

And you can loop over one, you just don’t control the order:

Apex
for (String taco : tacos)
{
    System.debug(taco);   //all of them, order not guaranteed
}

Full method list is in the Set class documentation.


Where Sets Genuinely Shine

Here’s the pattern you’ll write approximately nine thousand times in your Salesforce career.

You’ve got a pile of Contacts. You need the Accounts they belong to. Loads of those Contacts share an Account, so if you just collect Account Ids into a list you’ll end up with the same Id twenty times.

Apex
List<Contact> contacts = [SELECT Id, AccountId FROM Contact LIMIT 200];

Set<Id> accountIds = new Set<Id>();

for (Contact cont : contacts)
{
    accountIds.add(cont.AccountId);   //duplicates handled automatically
}

//One clean query, no repeated Ids
List<Account> accounts = [SELECT Id, Name FROM Account WHERE Id IN :accountIds];

That’s it. No checking whether you’ve already added something, no deduplicating afterwards. The set just handles it.

Try that with a list and you’d need a contains() check on every iteration, which works but is slower and uglier. Whenever you’re gathering Ids to query on, reach for a Set.


They’re Also Faster For Lookups

Worth knowing: contains() on a Set is dramatically faster than on a List.

A List has to walk through every item one at a time until it finds a match. A Set hashes the value and jumps more or less straight to the answer. With ten items you’d never notice. With ten thousand, checked inside a loop, you very much will.

So if all you need to know is “have I seen this before?”, a Set is the right tool.


One Gotcha With SObjects

A Set<Account> compares whole records, every field, not just the Id. So two Accounts with the same Id but a different Name count as different items and both go in.

That’s rarely what people expect. If you want unique records, key off the Id, and honestly at that point what you actually want is a Map, which is conveniently the next episode.


What’s Next

Sets: unordered, no duplicates, no index access, fast lookups. Use them for collecting Ids and for “have I seen this?” checks.

In the next episode, Maps. They intimidated me for far too long when I was learning, and they turn out to be one of the most useful things in the language.

See you next time!


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Good Non-SF Specific Development Books:

Clean Code
Clean Architecture