As a Salesforce developer, I find I frequently need to extract Sets from List<SObject>, so I'm looking to create a generalized way of creating Sets.

The problem is, Salesforce thinks Set<Object> is never an instance of Set<Id>, Set<String>, etc.

I've created this helper class:

    private class SetExtractor {
        SObjectField extractedField;
        XAP_PRED_SObjectPredicateIntf predicate;

        SetExtractor(SObjectField extractedField, XAP_PRED_SObjectPredicateIntf predicate) {
            this.extractedField = extractedField;
            this.predicate = predicate;

        SetExtractor(SObjectField extractedField) {
            this(extractedField, new XAP_PRED_SObjectFieldHasNonBlankValue(extractedField) 

        public Set<Object> extractFrom(List<SObject> sObjectList) {
            Set<Object> resultSet = new Set<Object>();
            for (SObject sObj : sObjectList) {
                if (this.predicate.isTrueFor(sObj)) {
            return resultSet;

This is the Predicate interface:

public interface XAP_PRED_SObjectPredicateIntf {
    Boolean isTrueFor(SObject sObj);

I can solve the problem of converting from Set<Object> to Set<Id> using serialize/deserialize, for example:

public virtual Set<Id> extractNonNullIdsFrom(List<SObject> sObjectList, SObjectField idField) {
    Set<Object> objectSet = new SetExtractor(idField)
    return (Set<Id>) JSON.deserialize(JSON.serialize(objectSet), Set<Id>.class);

But it is my understanding that serialize/deserialize are expensive operations.

Alternatively, instead of initially extracting a Set, I could extract a List, i.e.:

public virtual Set<Id> extractNonNullIdsFrom(List<SObject> sObjectList, SObjectField idField) {
    List<Object> objectList = new ListForSetExtractor(idField)
    return new Set<Id>((List<Id>)objectList);
  • I'm wondering if there is a downside to this later approach?
  • Would the size of either the source sObjectList or the result objectList matter?
  • If so, what might be a good way to determine the tipping point?

1 Answer 1


Why not just use Map Constructor? and then use the keySet to get Set?

Set<Id> resultIds = (new Map<Id,SObject>(sObjectList)).keySet();
  • Good question... Let me share more code to make it more clear what I am doing. :-) May 1, 2019 at 15:17
  • I've added some code. By the way, you'll notice that here I'm not just getting the keySet, but possibly any Ids contained in the SObject. Or, more abstractly, I could get any set of values which meets the predicate criteria. May 1, 2019 at 15:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .