Skip to main content
Deepak Sharma preguntó en #Apex

Hi Trailblazers, 

 

In an Apex implementation, I need to group and process records dynamically and I’m evaluating nested collection approaches such as:

List<List<String>> groupedData;

and

Map<String, List<String>> groupedData;

For record grouping, Map<Key, List<T>> seems more practical, but I’d like to understand:

  • When would List<List<T>> be a better choice in a real-time project?
  • Are there any performance or governor-limit considerations?
  • What approach do you generally prefer when grouping SOQL results?

Would appreciate any real-world examples or best practices.

Thanks !!.  

 

#Apex  #Salesforce Developer  #Trailhead  #TrailblazerCommunity

1 respuesta
  1. 20 ago, 12:51

    Hi Deepak - for grouping, Map<Key, List<T>> is almost always the right call. List<List<T>> is rarely right for grouping because you lose the key (no O(1) lookup - you would have to scan to find a group). 

     

    When to prefer each: 

    - Map<Key, List<T>>: anytime you group BY something, e.g. Map<Id, List<Contact>> keyed by AccountId. O(1) lookup, keys auto-dedup, and it is the bulkification backbone in triggers. 

    - List<List<T>>: only when there is no meaningful key and the split is positional - fixed-size chunks for a callout that takes N records per request, or partitioning work across async jobs. You just iterate the sublists, never look up by key. 

     

    Governor / performance: 

    - The limit that actually bites is HEAP (6 MB sync / 12 MB async), driven by how many records you hold in memory, not the collection shape. Map's key overhead is negligible. 

    - Map's real win is avoiding nested loops: correlating two lists via a Map is O(n); scanning a List<List<>> to find a group re-introduces O(n-squared). That is the real consideration. 

    - Neither changes SOQL/DML limits - those depend on bulkifying, which you do either way. 

     

    Pattern I use for grouping SOQL results: 

    Map<Id, List<Contact>> byAcct = new Map<Id, List<Contact>>(); 

    for (Contact c : [SELECT Id, AccountId FROM Contact]) { 

      if (!byAcct.containsKey(c.AccountId)) byAcct.put(c.AccountId, new List<Contact>()); 

      byAcct.get(c.AccountId).add(c); 

     

    Two more: for a true parent-child group, a subquery like [SELECT Id, (SELECT Id FROM Contacts) FROM Account] groups it at the query level - often cleaner. And for two dimensions, Map<Key1, Map<Key2, List<T>>> stays keyed and O(1). 

     

    Net: default to Map<Key, List<T>> for grouping; reach for List<List<T>> only for keyless chunking. 

     

    If this helps, please mark it as the Best Answer so it helps the next person - thanks :)

0/9000