Collection of List keyed by sObject field

Is it possible to have a Map (or other collection) of sObjects list, keyed by one lookup field of the same sObject.

Something like Maps of sObjects (below code doesn’t works):

Map<Id, List<Custom__c>> itemsMap = new Map<Id, List<Custom__c>>([SELECT Lookup_To_Custom__r.Id, Name FROM Custom__c]);

Note: this gives the following error Invalid initial type LIST<Custom__c> for MAP<Id,LIST<Custom__c>>

Were the Idin Map<Id, List<Custom__c>> is a reference to the Lookup_To_Custom__r.Id field.


Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The special map constructor only handles the case of creating a map where the key is the ID and the value is the SObject.

To do what I think you want to do requires a loop:

Map<Id, List<Custom__c>> m = new  Map<Id, List<Custom__c>>();
for (Custom__c c : [
        SELECT Lookup_To_Custom__c, Id, Name
        FROM Custom__c
        WHERE Lookup_To_Custom__c != null
        ORDER BY Name
        ]) {
    List<Custom__c> l = m.get(c.Lookup_To_Custom__c);
    if (l == null) {
        l = new List<Custom__c>();
        m.put(c.Lookup_To_Custom__c, l);

Note that using the foreign key field Lookup_To_Custom__c is a little more direct than going through the reference and taking the ID Lookup_To_Custom__r.Id.

Method 2

This is certainly possible. You just need to build the map yourself instead of trying to create it form a a single query.

As an example lets say we have a custom lookup on the contact record to another contact, say ‘Emergency Contact’. Its possible that a person is listed as the emergency contact for more 1 person, so we could create a map where the key is the contact id, and the value is actually a list of contacts in which they are the emergency contact for.

Obviously this is a bit different from your case, but the same idea and you should easily be able to adjust the code for your scenario.

Map<Id, List<Contact>> conMap = new Map<Id, List<Contact>>();
for(Contact parent : [Select Id, Name, (Select Id, Name From EmergencyContacts__r) From Contact]) {
    conMap.put(parent.Id, new list<Contact>());
    for(Contact child : parent.EmergencyContacts__r){
system.debug('My Map: ' + conMap);

You now have a map where a contact Id is the key, and a list of contacts that person is the emergency contact for is the value.

Hope that helps


Thinking about it more, you could likely make trim this down a bit more and just do this as well.

Map<Id, List<Contact>> conMap = new Map<Id, List<Contact>>();
for(Contact parent : [Select Id, Name, (Select Id, Name From EmergencyContacts) From Contact]) {
    conMap.put(parent.Id, parent.EmergencyContacts__r);

system.debug('My Map: ' + conMap);

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x