Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I was trying to use set.addAll method with a list of SObject, but I was not able to make it work. Is there any restriction with this data type?

Documentation doesn't mention any: Salesforce Set methods doc

List<String> myList = new List<String>{'Test1','Test2','Test3'};
Set<String> mySet = new Set<String>();
Boolean areInserted = mySet.addAll(myList);
System.debug('Check with SObjectType');
Schema.DescribeFieldResult productFieldResult = Schema.sObjectType.MyObject__c.fields.Product__c;
List<SObjectType> fieldResults = productFieldResult.getReferenceTo();
Set<SObjectType> fieldResultsSet = new Set<SObjectType>();
Boolean areInserted2 = fieldResultsSet.addAll(fieldResults);
System.debug('Try with loop');
List<SObjectType> mySet2 = new List<SObjectType>();
for(SObjectType objType : fieldResults)

Finds here the debug result.

enter image description here

Thanks, Agustina

share|improve this question
up vote 2 down vote accepted

On the subject of whether contains works or not, I couldn't find a failing case with these simple tests (whether using standard or custom objects):

private class SetTest {

    static void containsAndAddAll() {

        Set<SObjectType> s = new Set<SObjectType>{

        Set<SObjectType> ss = new Set<SObjectType>();

    private static void assertContactAndAccountOnly(Set<SObjectType> s) {

        System.assertEquals(false, s.contains(Task.SObjectType));
        System.assertEquals(true, s.contains(Contact.SObjectType));
        System.assertEquals(true, s.contains(Account.SObjectType));
        System.assertEquals(false, s.contains(Note.SObjectType));
        System.assertEquals(2, s.size());

    static void addAndRemove() {

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

        // Add
        System.assertEquals(0, s.size());
        System.assertEquals(1, s.size());
        System.assertEquals(2, s.size());
        System.assertEquals(true, s.contains(Task.SObjectType));
        System.assertEquals(true, s.contains(Note.SObjectType));

        // Remove
        System.assertEquals(1, s.size());
        System.assertEquals(true, s.contains(Task.SObjectType));
        System.assertEquals(false, s.contains(Note.SObjectType));
        System.assertEquals(0, s.size());
        System.assertEquals(false, s.contains(Task.SObjectType));
        System.assertEquals(false, s.contains(Note.SObjectType));
share|improve this answer
You are adding set.addAll(Set<SObjectType>) and my issue was with set.addAll(List<SObjectType>). However y tried again and works now. Apologize. – Agustina García Mar 31 '14 at 10:37

The problem you are seeing is that for some reason the string representation of Set and List when they contain SObjectType is wrong making it appear that they are empty. If you invoke other methods such as size or contains you will see the behaviour you expect. Your test hints at that by addAll returning true.

I'd call this behaviour a bug, but I don't think the string representation is documented anywhere...

A work around (to help with debugging) would be to write a utility method that builds the string representation by iterating over the content and appending to a string e.g.:

public class Util {
    public static String toString(Set<SObjectType> sobTypes) {
        return toString(new List<SObjectType>(sobTypes));
    public static String toString(List<SObjectType> sobTypes) {
        // Note that String.join doesn't work here at present
        String s = '';
        for (SObjectType sobType : sobTypes) {
            if (s != '') {
                s += ', ';
            s += sobType;
        return '{' + s + '}';
share|improve this answer
Ah beat me to it Keith! Nice one! – Andrew Fawcett Mar 28 '14 at 12:41
@AndrewFawcett Think I'd seen this problem in my own debugging before - a real time waster. – Keith C Mar 28 '14 at 12:47
Yeah I can imagine, btw, rollout the new String.join function in your above example to make a little leaner... ;-) – Andrew Fawcett Mar 28 '14 at 12:50
@AndrewFawcett Aaargh keep doing this. I'll change it thanks. – Keith C Mar 28 '14 at 12:51
@AndrewFawcett Tried String.join for a couple of SObjectTypes and it output "{common.apex.runtime.impl.ApexSObjectTypeToken@6d95f8ef, common.apex.runtime.impl.ApexSObjectTypeToken@110a4b1e}"; looks like the handling of these tokens is broken in more than one place... – Keith C Mar 28 '14 at 13:02

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.