Sign up ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

It seems like it should return a set instead, but it returns a list. Why is that?

share|improve this question
If you used a set, presumably you couldn't then have two identical records in the insertion/update list. The difference between two records may just be the ID, which of course will not be present prior to an insert –  Phil Hawthorn Jun 17 '14 at 19:52
Also a list is ordered, and it is very often useful to be able to compare the values of old and new during trigger processing, which you can do by comparing old[x] with new[x] –  Doug B Jun 17 '14 at 19:55
Why do you think it should return a set? –  Doug B Jun 17 '14 at 19:59
I'm not sure I see the benefit of returning a set, in general sets aren't well designed for objects, and are better used with primitives ... whyat were you expecting? –  Ralph Callaway Jun 17 '14 at 20:10

2 Answers 2

There are several reasons for this:

Sets have Collisions

In a set, you can't have duplicate values. This means that if someone did this:

insert new Account[] { new Account(Name='Test'), new Account(Name='Test') }; would contain only one entry in a before insert trigger.

Set<Account> accs = new Set<Account>{ new Account(Name='Test'), new Account(Name='Test') };
System.assertEquals(1, accs.size());

Sets are Unordered and Trigger.old are ordered in the same way, so that you can guarantee[12] matches Trigger.old[12].

You wouldn't be able to compare old and new values directly without resorting to trigger.newmap and trigger.oldmap (which before insert would again have problems with).

You can't do this with a set:

for(Integer index = 0; index <; index++) {
    // Compare[index] and Trigger.old[index]
share|improve this answer
After they managed to screw up Id uniqueness (granted, "only" in queries) I've developed some serious FUD about this... I think your comment about "before insert" should say "after insert" ("before" is empty) - in which case I agree, if ever order of old & new becomes unreliable - we're screwed in "after insert". –  eyescream Jun 17 '14 at 20:25
@sfdcfox- on the insert example above, wouldn't they be unique at time of insert because they have unique IDs? –  Niv Jun 17 '14 at 20:43
@nivyaj In a before insert trigger, the ID values are blank, because the server hasn't had a commit yet, so the auto-generated ID values don't exist yet. That means that a before insert trigger set would result in a collapse of the records. –  sfdcfox Jun 17 '14 at 20:55
@eyescream No, I meant before insert-- Trigger.newMap doesn't work because it references values by ID, which are still null. Trigger.newMap works normally in after insert, but that does cripple our ability to perform certain types of optimizations that are thankfully rare. –  sfdcfox Jun 17 '14 at 21:01
But before insert the trigger.old(Map) is useless, you have nothing to compare against. So "before insert" isn't a good example here I think. –  eyescream Jun 17 '14 at 21:04

A list is ordered, and it is very often useful to be able to compare the values of old and new during trigger processing, which you can do by comparing old[x] with new[x]

share|improve this answer
@eyescream That code refers to a query. Trigger.old[x] will correspond to[x]. –  sfdcfox Jun 17 '14 at 20:01

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.