MAP_SObject
Class · Group: Utilities
global inherited sharing class MAP_SObjectIn-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).
// 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
Since: 1.0
Example:
MAP_SObject contactsByAccountId = MAP_SObject.of(contacts, 'AccountId');
List<Contact> accountContacts = contactsByAccountId.getAll(someAccountId);
Contact first = (Contact)contactsByAccountId.get(someAccountId);Methods
| Method | Description |
|---|---|
| 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 getAll(Map<String, Object> fieldValueMap) | Retrieves all SObjects matching the field-value map for indexed fields. |
| global List getAll(Object key) | Retrieves all SObjects matching the specified key. |
| global List 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 keySet() | Retrieves the set of unique keys for the current index level. |
| global Set keySet(String field) | Retrieves the set of unique keys for a specific field in the index. |
| 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. |
| global static MAP_SObject of(List<List<String> fieldNames) | Creates an index from a list of records indexed by multiple fields. |
| global static MAP_SObject of(List<SObject> records, SObject 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 remove(Map<String, Object> fieldValueMap) | Removes SObjects matching the field-value map from the index. |
| global List 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 values() | Retrieves all SObjects stored in the index. |
Method Details
MAP_SObject
global MAP_SObject(List<String> indexFields)Initializes a new MAP_SObject with multiple indexed fields.
Parameters:
indexFields(List) - The list of fields to index.
Since: 1.0
Example:
MAP_SObject index = new MAP_SObject(new List<String>{'AccountId', 'LastName'});MAP_SObject
global MAP_SObject(String fieldName)Initializes a new MAP_SObject with a single indexed field.
Parameters:
fieldName(String) - The name of the field to index.
Since: 1.0
Example:
MAP_SObject index = new MAP_SObject('Name');caseInsensitive
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.
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(contacts, 'Email').caseInsensitive();
Contact c = (Contact)index.get('JOHN@EXAMPLE.COM');clear
global void clear()Removes all records from the index, allowing it to be reused or explicitly freeing memory.
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(accounts, 'Industry');
index.clear();
Assert.isTrue(index.isEmpty());containsKey
global Boolean containsKey(Object key)Checks if the index contains records for the specified key at the first index level.
Parameters:
key(Object) - A value for the first indexed field.
Returns: Boolean - true if records exist for the key, false otherwise.
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(accounts, 'Industry');
if(index.containsKey('Technology'))
{
// Process technology accounts
}get
global SObject get(Object key)Retrieves a single SObject matching the specified key.
Parameters:
key(Object) - A value for the indexed field.
Returns: SObject - A matching SObject, or null if no match is found (returns the first match if multiple exist).
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(accounts, 'Id');
Account acc = (Account)index.get(someAccountId);get
global SObject get(SObject specification)Retrieves a single SObject matching the specification SObject on all indexed fields.
Parameters:
specification(SObject) - An 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).
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
Contact c = (Contact)index.get(new Contact(AccountId = accId, LastName = 'Smith'));getAll
global List<SObject> getAll(Map<String, Object> fieldValueMap)Retrieves all SObjects matching the field-value map for indexed fields.
Parameters:
fieldValueMap(Map) - A map of field names to values.
Returns: SObject - A list of matching SObjects, or an empty list if no matches are found.
Since: 1.0
Example:
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);getAll
global List<SObject> getAll(Object key)Retrieves all SObjects matching the specified key.
Parameters:
key(Object) - A value for the indexed field.
Returns: SObject - A list of matching SObjects, or an empty list if no matches are found.
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(contacts, 'AccountId');
List<Contact> accountContacts = index.getAll(someAccountId);getAll
global List<SObject> getAll(SObject specification)Retrieves all SObjects matching the specification SObject on all indexed fields.
Parameters:
specification(SObject) - An SObject with values for all indexed fields.
Returns: SObject - A list of matching SObjects, or an empty list if no matches are found.
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
List<Contact> results = index.getAll(new Contact(AccountId = accId, LastName = 'Smith'));getSubIndex
global MAP_SObject getSubIndex(Object key)Retrieves a sub-index for entries matching the specified key.
Parameters:
key(Object) - A value for the first indexed field.
Returns: MAP_SObject - A MAP_SObject for matching entries, or null if no match is found.
Since: 1.0
Example:
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
global Boolean isEmpty()Checks if the index is empty.
Returns: Boolean - true if the index is empty, false otherwise.
Since: 1.0
Example:
MAP_SObject index = new MAP_SObject('Name');
Boolean isEmpty = index.isEmpty(); // Returns truekeySet
global Set<String> keySet()Retrieves the set of unique keys for the current index level.
Returns: String - A set of string keys.
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(accounts, 'Industry');
Set<String> industries = index.keySet();keySet
global Set<String> keySet(String field)Retrieves the set of unique keys for a specific field in the index.
Parameters:
field(String) - The field name to retrieve keys for.
Returns: String - A set of string keys.
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
Set<String> lastNames = index.keySet('LastName');of
global static MAP_SObject of(List<SObject> records, List<String> fieldNames)Creates an index from a list of records indexed by multiple fields.
Parameters:
Returns: MAP_SObject - A new MAP_SObject containing the indexed records.
Since: 1.0
Example:
MAP_SObject contactsByAccountAndName = MAP_SObject.of(contacts, new List<String>{'AccountId', 'LastName'});
List<Contact> contacts = contactsByAccountAndName.getAll(new Contact(AccountId = accId, LastName = 'Smith'));of
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:
Returns: MAP_SObject - A new MAP_SObject containing the indexed records.
Since: 1.0
Example:
MAP_SObject accountsById = MAP_SObject.of(accounts, Account.Id);
Account acc = (Account)accountsById.get(someId);of
global static MAP_SObject of(List<SObject> records, String fieldName)Creates an index from a list of records indexed by a single field.
Parameters:
Returns: MAP_SObject - A new MAP_SObject containing the indexed records.
Since: 1.0
Example:
MAP_SObject accountsById = MAP_SObject.of(accounts, 'Id');
Account acc = (Account)accountsById.get(someId);put
global MAP_SObject put(SObject sObjectToAdd)Adds a single SObject to the index.
Parameters:
sObjectToAdd(SObject) - The SObject to add.
Returns: MAP_SObject - This MAP_SObject instance for method chaining.
Since: 1.0
Example:
MAP_SObject index = new MAP_SObject('Name');
index.put(new Account(Name='Acme'));putAll
global MAP_SObject putAll(List<SObject> sObjectsToAdd)Adds a list of SObjects to the index.
Parameters:
sObjectsToAdd(List) - List of SObjects to add.
Returns: MAP_SObject - This MAP_SObject instance for method chaining.
Since: 1.0
Example:
MAP_SObject index = new MAP_SObject('Name');
index.putAll(new List<Account>{new Account(Name='Acme')});remove
global List<SObject> remove(Map<String, Object> fieldValueMap)Removes SObjects matching the field-value map from the index.
Parameters:
fieldValueMap(Map) - A map of field names to values.
Returns: SObject - A list of removed SObjects, or an empty list if no matches are found.
Since: 1.0
Example:
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);remove
global List<SObject> remove(SObject specification)Removes SObjects matching the specification SObject from the index.
Parameters:
specification(SObject) - An SObject with values for all indexed fields.
Returns: SObject - A list of removed SObjects, or an empty list if no matches are found.
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(contacts, 'AccountId');
List<SObject> removed = index.remove(new Contact(AccountId = accId));size
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.
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(contacts, 'AccountId');
System.debug('Indexed ' + index.size() + ' contacts');toString
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.
Since: 1.0
Example:
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
global List<SObject> values()Retrieves all SObjects stored in the index.
Returns: SObject - A list of all SObjects in the index.
Since: 1.0
Example:
MAP_SObject index = MAP_SObject.of(accounts, 'Industry');
List<SObject> allAccounts = index.values();