Skip to content

MAP_SObject

Class · Group: Utilities

apex
global inherited sharing class MAP_SObject

In-memory index for SObjects, indexed by one or more fields. Supports cross-object field references, case-insensitive matching, and hierarchical multi-field indexing.

Performance & Usage Guidelines

Use MAP_SObject when:

- **Grouping (1-to-Many):** You need to map a key to multiple records (e.g., "Get all Contacts by AccountId").

MAP_SObject handles list creation automatically, eliminating boilerplate null-checks.

- **Cross-Object Fields:** You need to index by relationship fields (e.g., `Account.Owner.Name`).

- **Composite Keys:** You need hierarchical indexing by multiple fields (e.g., AccountId then LastName).

- **Case-Insensitive Matching:** You need to match keys regardless of case without manual string normalization.

Use native Map<Id, SObject> instead when:

- **Unique Primary Keys:** You are indexing by Id or a unique field where 1 Key = 1 Record.

Native Apex Maps are approximately 5-10x faster and consume less heap memory than this utility. Always prefer native Maps for simple ID lookups in performance-critical code paths (e.g., triggers).

apex
// BAD: Using MAP_SObject for unique ID lookups
MAP_SObject accountsById = MAP_SObject.of(accounts, 'Id');
Account account = (Account)accountsById.get(someId);

// GOOD: Using native Map for unique ID lookups
Map<Id, Account> accountsById = new Map<Id, Account>(accounts);
Account account = accountsById.get(someId);

// GOOD: Using MAP_SObject for 1-to-Many grouping
MAP_SObject contactsByAccountId = MAP_SObject.of(contacts, 'AccountId');
List<Contact> accountContacts = contactsByAccountId.getAll(someAccountId);

Adapted from: SObjectIndex

Example

apex
MAP_SObject contactsByAccountId = MAP_SObject.of(contacts, 'AccountId');
List<Contact> accountContacts = contactsByAccountId.getAll(someAccountId);
Contact first = (Contact)contactsByAccountId.get(someAccountId);

Methods

MethodDescription
global MAP_SObject caseInsensitive()Enables case-insensitive key matching.
global void clear()Removes all records from the index, allowing it to be reused or explicitly freeing memory.
global Boolean containsKey(Object key)Checks if the index contains records for the specified key at the first index level.
global SObject get(Object key)Retrieves a single SObject matching the specified key.
global SObject get(SObject specification)Retrieves a single SObject matching the specification SObject on all indexed fields.
global List<SObject> getAll(Map<String, Object> fieldValueMap)Retrieves all SObjects matching the field-value map for indexed fields.
global List<SObject> getAll(Object key)Retrieves all SObjects matching the specified key.
global List<SObject> getAll(SObject specification)Retrieves all SObjects matching the specification SObject on all indexed fields.
global MAP_SObject getSubIndex(Object key)Retrieves a sub-index for entries matching the specified key.
global Boolean isEmpty()Checks if the index is empty.
global Set<String> keySet()Retrieves the set of unique keys for the current index level.
global Set<String> keySet(String field)Retrieves the set of unique keys for a specific field in the index.
global static MAP_SObject of(List<SObject> records, List<String> fieldNames)Creates an index from a list of records indexed by multiple fields.
global static MAP_SObject of(List<SObject> records, SObjectField field)Creates an index from a list of records indexed by a single field token.
global static MAP_SObject of(List<SObject> records, String fieldName)Creates an index from a list of records indexed by a single field.
global MAP_SObject put(SObject sObjectToAdd)Adds a single SObject to the index.
global MAP_SObject putAll(List<SObject> sObjectsToAdd)Adds a list of SObjects to the index.
global List<SObject> remove(Map<String, Object> fieldValueMap)Removes SObjects matching the field-value map from the index.
global List<SObject> remove(SObject specification)Removes SObjects matching the specification SObject from the index.
global Integer size()Returns the total number of SObjects stored in the index.
global override String toString()Returns a string representation of the index structure for debugging purposes.
global List<SObject> values()Retrieves all SObjects stored in the index.

caseInsensitive

apex
global MAP_SObject caseInsensitive()

Enables case-insensitive key matching. Must be called on an empty index.

Returns MAP_SObject — This MAP_SObject instance for method chaining.

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, 'Email').caseInsensitive();
Contact c = (Contact)index.get('JOHN@EXAMPLE.COM');

clear

apex
global void clear()

Removes all records from the index, allowing it to be reused or explicitly freeing memory.

Example

apex
MAP_SObject index = MAP_SObject.of(accounts, 'Industry');
index.clear();
Assert.isTrue(index.isEmpty());

containsKey

apex
global Boolean containsKey(Object key)

Checks if the index contains records for the specified key at the first index level.

Parameters

ParameterTypeDescription
keyObjectA value for the first indexed field.

Returns Booleantrue if records exist for the key, false otherwise.

Example

apex
MAP_SObject index = MAP_SObject.of(accounts, 'Industry');
if(index.containsKey('Technology'))
{
    // Process technology accounts
}

get

apex
global SObject get(Object key)

Retrieves a single SObject matching the specified key.

Parameters

ParameterTypeDescription
keyObjectA value for the indexed field.

Returns SObject — A matching SObject, or null if no match is found (returns the first match if multiple exist).

Example

apex
MAP_SObject index = MAP_SObject.of(accounts, 'Id');
Account acc = (Account)index.get(someAccountId);
apex
global SObject get(SObject specification)

Retrieves a single SObject matching the specification SObject on all indexed fields.

Parameters

ParameterTypeDescription
specificationSObjectAn SObject with values for all indexed fields.

Returns SObject — A matching SObject, or null if no match is found (returns the first match if multiple exist).

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
Contact c = (Contact)index.get(new Contact(AccountId = accId, LastName = 'Smith'));

getAll

apex
global List<SObject> getAll(Map<String, Object> fieldValueMap)

Retrieves all SObjects matching the field-value map for indexed fields.

Parameters

ParameterTypeDescription
fieldValueMapMapA map of field names to values.

Returns SObject — A list of matching SObjects, or an empty list if no matches are found.

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
Map<String, Object> spec = new Map<String, Object>{ 'LastName' => 'Smith' };
List<Contact> results = index.getAll(spec);
apex
global List<SObject> getAll(Object key)

Retrieves all SObjects matching the specified key.

Parameters

ParameterTypeDescription
keyObjectA value for the indexed field.

Returns SObject — A list of matching SObjects, or an empty list if no matches are found.

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, 'AccountId');
List<Contact> accountContacts = index.getAll(someAccountId);
apex
global List<SObject> getAll(SObject specification)

Retrieves all SObjects matching the specification SObject on all indexed fields.

Parameters

ParameterTypeDescription
specificationSObjectAn SObject with values for all indexed fields.

Returns SObject — A list of matching SObjects, or an empty list if no matches are found.

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
List<Contact> results = index.getAll(new Contact(AccountId = accId, LastName = 'Smith'));

getSubIndex

apex
global MAP_SObject getSubIndex(Object key)

Retrieves a sub-index for entries matching the specified key.

Parameters

ParameterTypeDescription
keyObjectA value for the first indexed field.

Returns MAP_SObject — A MAP_SObject for matching entries, or null if no match is found.

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
MAP_SObject accountContacts = index.getSubIndex(someAccountId);
List<Contact> smiths = accountContacts.getAll('Smith');

isEmpty

apex
global Boolean isEmpty()

Checks if the index is empty.

Returns Booleantrue if the index is empty, false otherwise.

Example

apex
MAP_SObject index = new MAP_SObject('Name');
Boolean isEmpty = index.isEmpty(); // Returns true

keySet

apex
global Set<String> keySet()

Retrieves the set of unique keys for the current index level.

Returns String — A set of string keys.

Example

apex
MAP_SObject index = MAP_SObject.of(accounts, 'Industry');
Set<String> industries = index.keySet();
apex
global Set<String> keySet(String field)

Retrieves the set of unique keys for a specific field in the index.

Parameters

ParameterTypeDescription
fieldStringThe field name to retrieve keys for.

Returns String — A set of string keys.

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
Set<String> lastNames = index.keySet('LastName');

of

apex
global static MAP_SObject of(List<SObject> records, List<String> fieldNames)

Creates an index from a list of records indexed by multiple fields.

Parameters

ParameterTypeDescription
recordsListThe records to index.
fieldNamesSObjectThe fields to index by (hierarchical).

Returns MAP_SObject — A new MAP_SObject containing the indexed records.

Example

apex
MAP_SObject contactsByAccountAndName = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
List<Contact> contacts = contactsByAccountAndName.getAll(new Contact(AccountId = accId, LastName = 'Smith'));
apex
global static MAP_SObject of(List<SObject> records, SObjectField field)

Creates an index from a list of records indexed by a single field token.

Parameters

ParameterTypeDescription
recordsListThe records to index.
fieldSObjectThe field token to index by.

Returns MAP_SObject — A new MAP_SObject containing the indexed records.

Example

apex
MAP_SObject accountsById = MAP_SObject.of(accounts, Account.Id);
Account acc = (Account)accountsById.get(someId);
apex
global static MAP_SObject of(List<SObject> records, String fieldName)

Creates an index from a list of records indexed by a single field.

Parameters

ParameterTypeDescription
recordsListThe records to index.
fieldNameSObjectThe field to index by.

Returns MAP_SObject — A new MAP_SObject containing the indexed records.

Example

apex
MAP_SObject accountsById = MAP_SObject.of(accounts, 'Id');
Account acc = (Account)accountsById.get(someId);

put

apex
global MAP_SObject put(SObject sObjectToAdd)

Adds a single SObject to the index.

Parameters

ParameterTypeDescription
sObjectToAddSObjectThe SObject to add.

Returns MAP_SObject — This MAP_SObject instance for method chaining.

Example

apex
MAP_SObject index = new MAP_SObject('Name');
index.put(new Account(Name='Acme'));

putAll

apex
global MAP_SObject putAll(List<SObject> sObjectsToAdd)

Adds a list of SObjects to the index.

Parameters

ParameterTypeDescription
sObjectsToAddListList of SObjects to add.

Returns MAP_SObject — This MAP_SObject instance for method chaining.

Example

apex
MAP_SObject index = new MAP_SObject('Name');
index.putAll(new List<Account>{new Account(Name='Acme')});

remove

apex
global List<SObject> remove(Map<String, Object> fieldValueMap)

Removes SObjects matching the field-value map from the index.

Parameters

ParameterTypeDescription
fieldValueMapMapA map of field names to values.

Returns SObject — A list of removed SObjects, or an empty list if no matches are found.

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
Map<String, Object> spec = new Map<String, Object>{ 'LastName' => 'Smith' };
List<SObject> removed = index.remove(spec);
apex
global List<SObject> remove(SObject specification)

Removes SObjects matching the specification SObject from the index.

Parameters

ParameterTypeDescription
specificationSObjectAn SObject with values for all indexed fields.

Returns SObject — A list of removed SObjects, or an empty list if no matches are found.

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, 'AccountId');
List<SObject> removed = index.remove(new Contact(AccountId = accId));

size

apex
global Integer size()

Returns the total number of SObjects stored in the index. More efficient than values().size() as it counts recursively without materializing the full list.

Returns Integer — The total count of indexed SObjects.

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, 'AccountId');
System.debug('Indexed ' + index.size() + ' contacts');

toString

apex
global override String toString()

Returns a string representation of the index structure for debugging purposes.

Returns String — A string showing the index field, depth, and current keys.

Example

apex
MAP_SObject index = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
System.debug(index); // Outputs: MAP_SObject[field=AccountId, depth=0, keys={001...}]

values

apex
global List<SObject> values()

Retrieves all SObjects stored in the index.

Returns SObject — A list of all SObjects in the index.

Example

apex
MAP_SObject index = MAP_SObject.of(accounts, 'Industry');
List<SObject> allAccounts = index.values();

Constructors

ConstructorDescription
global MAP_SObject(List<String> indexFields)Initializes a new MAP_SObject with multiple indexed fields.
global MAP_SObject(String fieldName)Initializes a new MAP_SObject with a single indexed field.

MAP_SObject(List<String> indexFields)

apex
global MAP_SObject(List<String> indexFields)

Initializes a new MAP_SObject with multiple indexed fields.

Parameters

ParameterTypeDescription
indexFieldsListThe list of fields to index.

Example

apex
MAP_SObject index = new MAP_SObject(new List<String>{'AccountId', 'LastName'});

MAP_SObject(String fieldName)

apex
global MAP_SObject(String fieldName)

Initializes a new MAP_SObject with a single indexed field.

Parameters

ParameterTypeDescription
fieldNameStringThe name of the field to index.

Example

apex
MAP_SObject index = new MAP_SObject('Name');