Take the 2-minute tour ×
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.

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'};
System.debug(myList);
Set<String> mySet = new Set<String>();
Boolean areInserted = mySet.addAll(myList);
System.debug(areInserted);
System.debug(mySet);
System.debug('Check with SObjectType');
Schema.DescribeFieldResult productFieldResult = Schema.sObjectType.MyObject__c.fields.Product__c;
List<SObjectType> fieldResults = productFieldResult.getReferenceTo();
System.debug(fieldResults);
Set<SObjectType> fieldResultsSet = new Set<SObjectType>();
Boolean areInserted2 = fieldResultsSet.addAll(fieldResults);
System.debug(areInserted2);
System.debug(fieldResultsSet);
System.debug('Try with loop');
List<SObjectType> mySet2 = new List<SObjectType>();
for(SObjectType objType : fieldResults)
{
    mySet2.add(objType);
}
System.debug(mySet2);

Finds here the debug result.

enter image description here

Thanks, Agustina

share|improve this question

2 Answers 2

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):

@isTest
private class SetTest {

    @isTest
    static void containsAndAddAll() {

        Set<SObjectType> s = new Set<SObjectType>{
                Contact.SObjectType,
                Account.SObjectType
                };
        assertContactAndAccountOnly(s);

        Set<SObjectType> ss = new Set<SObjectType>();
        ss.addAll(s);
        assertContactAndAccountOnly(ss);
    }

    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());
    }

    @isTest
    static void addAndRemove() {

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

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

        // Remove
        s.remove(Note.SObjectType);
        System.assertEquals(1, s.size());
        System.assertEquals(true, s.contains(Task.SObjectType));
        System.assertEquals(false, s.contains(Note.SObjectType));
        s.remove(Task.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 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
1  
Ah beat me to it Keith! Nice one! –  Andrew Fawcett Mar 28 at 12:41
1  
@AndrewFawcett Think I'd seen this problem in my own debugging before - a real time waster. –  Keith C Mar 28 at 12:47
1  
Yeah I can imagine, btw, rollout the new String.join function in your above example to make a little leaner... ;-) –  Andrew Fawcett Mar 28 at 12:50
1  
@AndrewFawcett Aaargh keep doing this. I'll change it thanks. –  Keith C Mar 28 at 12:51
1  
@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 at 13:02

Your Answer

 
discard

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.