How does class Map work?
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
I trying to learn Triggers from TrailHead, but not able to understand this line of code.
Map<Id,Account> acctsWithOpps = new Map<Id,Account>(
[SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New]);
apex soql map inner-join
add a comment |Â
up vote
1
down vote
favorite
I trying to learn Triggers from TrailHead, but not able to understand this line of code.
Map<Id,Account> acctsWithOpps = new Map<Id,Account>(
[SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New]);
apex soql map inner-join
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I trying to learn Triggers from TrailHead, but not able to understand this line of code.
Map<Id,Account> acctsWithOpps = new Map<Id,Account>(
[SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New]);
apex soql map inner-join
I trying to learn Triggers from TrailHead, but not able to understand this line of code.
Map<Id,Account> acctsWithOpps = new Map<Id,Account>(
[SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New]);
apex soql map inner-join
apex soql map inner-join
edited 4 hours ago


Oleksandr Berehovskiy
8,51521835
8,51521835
asked 4 hours ago


Ansar Saeed
82
82
add a comment |Â
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
4
down vote
This is a unique Apex idiom. The Map class has a constructor that accepts a list of sObjects, such as the literal result of a SOQL query. The purpose of the constructor is to efficiently populate a Map between the Ids of the sObjects and the sObjects themselves.
This is useful in many places, but in triggers in particular it's often used when you're querying and using related objects. You'll typically need fast access to specific related objects based on their Ids stored in the records your trigger is processing. Using a Map allows you to index to those records directly rather than iterating through a list, which is very inefficient.
That pattern often looks like this:
Set<Id> myIdSet = new Set<Id>();
for (Contact c : Trigger.new)
myIdSet.add(c.AccountId);
Map<Id, Account> parentAccounts = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet]);
for (Contact c : Trigger.new)
Account accountForThisContact = parentAccounts.get(c.AccountId);
The critical bit is the line
Account accountForThisContact = parentAccounts.get(c.AccountId);
This allows us to immediately access queried Accounts (or any other sObject) by just its Id, with no iteration. Technically speaking, accessing a Map is an O(1) operation, which means it executes in constant time regardless of the number of records in the Map.
"unique" isn't exactly right. Maps exist in almost all modern languages.
– sfdcfox
56 mins ago
I was referring to the specific usagenew Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet])
, i.e., passing SOQL results directly into the Map constructor.
– David Reed
54 mins ago
add a comment |Â
up vote
1
down vote
SOQL query returns List
of Sobjects. In current case it returns List
of Accounts.
Map class have constructor, that accepts List
of Sobjects. Map<ID,sObject>(recordList)
. This constructor:
Creates a new instance of the Map class and populates it with the
passed-in list of sObject records. The keys are populated with the
sObject IDs and the values are the sObjects.
as a result of it, in your Map
keys are ids of queried Account
and values are queried Accounts.
The following code snippet illustrates this principle. Try it.
List<Account> accountsList = [
select Id, Name
from Account
];
Map<Id, Account> accountsMap = new Map<Id, Account>(accountsList);
for(Id accountId :accountsMap.keySet())
System.debug('Key:' + accountId + ', value:' + accountsMap.get(accountId));
add a comment |Â
up vote
0
down vote
Records are related to each other using Id
values i.e. one record references another record by having a (foreign key) field that contains the Id
of the other object. Triggers need to be written to handle the "bulk" case - many records at once - because the Salesforce platform puts limits on many operations such as making queries. So it is quite common that while looping over one list of SObjects, you want to find the data for the referenced object. That is where maps come in.
For example:
for (Contact c : Trigger.new)
Account a = acctsWithOpps.get(c.AccountId);
...
where here AccountId
is the foreign key field.
If maps were not used, the code would be more complicated and finding the matching object would be much more costly because the list would need to be looped over to find the match. A map divides up the data added so that a value can be quickly found largely independently of the number of records.
add a comment |Â
up vote
0
down vote
A SOQL query will always return a list of sobjects (only exception will be if using Aggregate queries then it can return an Integer or AggregatQueryResult)
Now There is a constructor for Map that accepts a List, and automatically makes the Sobject Id as its Key.
So the List of SObject can be passed to constuctor, So the single Line code can be written in few lines for Simplification like
List<Account> accList = [SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New];
Map<Id,Account> accountMap = new Map<Id,Account>(accList );
Also you can also get the list back from MAP using
List<Account> accList = accountMap.values();
Src: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_map.htm
"A SOQL query will always return a list of sobjects." Well it is not true actually. It can return also single SObject and Integer
– user1974566
50 mins ago
@user1974566 I agree with aggregate function exception, but it always returns a list. List with 1 element is still a list. Though you can assign it to an individual record it will always be a list.
– Pranay Jaiswal
48 mins ago
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
This is a unique Apex idiom. The Map class has a constructor that accepts a list of sObjects, such as the literal result of a SOQL query. The purpose of the constructor is to efficiently populate a Map between the Ids of the sObjects and the sObjects themselves.
This is useful in many places, but in triggers in particular it's often used when you're querying and using related objects. You'll typically need fast access to specific related objects based on their Ids stored in the records your trigger is processing. Using a Map allows you to index to those records directly rather than iterating through a list, which is very inefficient.
That pattern often looks like this:
Set<Id> myIdSet = new Set<Id>();
for (Contact c : Trigger.new)
myIdSet.add(c.AccountId);
Map<Id, Account> parentAccounts = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet]);
for (Contact c : Trigger.new)
Account accountForThisContact = parentAccounts.get(c.AccountId);
The critical bit is the line
Account accountForThisContact = parentAccounts.get(c.AccountId);
This allows us to immediately access queried Accounts (or any other sObject) by just its Id, with no iteration. Technically speaking, accessing a Map is an O(1) operation, which means it executes in constant time regardless of the number of records in the Map.
"unique" isn't exactly right. Maps exist in almost all modern languages.
– sfdcfox
56 mins ago
I was referring to the specific usagenew Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet])
, i.e., passing SOQL results directly into the Map constructor.
– David Reed
54 mins ago
add a comment |Â
up vote
4
down vote
This is a unique Apex idiom. The Map class has a constructor that accepts a list of sObjects, such as the literal result of a SOQL query. The purpose of the constructor is to efficiently populate a Map between the Ids of the sObjects and the sObjects themselves.
This is useful in many places, but in triggers in particular it's often used when you're querying and using related objects. You'll typically need fast access to specific related objects based on their Ids stored in the records your trigger is processing. Using a Map allows you to index to those records directly rather than iterating through a list, which is very inefficient.
That pattern often looks like this:
Set<Id> myIdSet = new Set<Id>();
for (Contact c : Trigger.new)
myIdSet.add(c.AccountId);
Map<Id, Account> parentAccounts = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet]);
for (Contact c : Trigger.new)
Account accountForThisContact = parentAccounts.get(c.AccountId);
The critical bit is the line
Account accountForThisContact = parentAccounts.get(c.AccountId);
This allows us to immediately access queried Accounts (or any other sObject) by just its Id, with no iteration. Technically speaking, accessing a Map is an O(1) operation, which means it executes in constant time regardless of the number of records in the Map.
"unique" isn't exactly right. Maps exist in almost all modern languages.
– sfdcfox
56 mins ago
I was referring to the specific usagenew Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet])
, i.e., passing SOQL results directly into the Map constructor.
– David Reed
54 mins ago
add a comment |Â
up vote
4
down vote
up vote
4
down vote
This is a unique Apex idiom. The Map class has a constructor that accepts a list of sObjects, such as the literal result of a SOQL query. The purpose of the constructor is to efficiently populate a Map between the Ids of the sObjects and the sObjects themselves.
This is useful in many places, but in triggers in particular it's often used when you're querying and using related objects. You'll typically need fast access to specific related objects based on their Ids stored in the records your trigger is processing. Using a Map allows you to index to those records directly rather than iterating through a list, which is very inefficient.
That pattern often looks like this:
Set<Id> myIdSet = new Set<Id>();
for (Contact c : Trigger.new)
myIdSet.add(c.AccountId);
Map<Id, Account> parentAccounts = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet]);
for (Contact c : Trigger.new)
Account accountForThisContact = parentAccounts.get(c.AccountId);
The critical bit is the line
Account accountForThisContact = parentAccounts.get(c.AccountId);
This allows us to immediately access queried Accounts (or any other sObject) by just its Id, with no iteration. Technically speaking, accessing a Map is an O(1) operation, which means it executes in constant time regardless of the number of records in the Map.
This is a unique Apex idiom. The Map class has a constructor that accepts a list of sObjects, such as the literal result of a SOQL query. The purpose of the constructor is to efficiently populate a Map between the Ids of the sObjects and the sObjects themselves.
This is useful in many places, but in triggers in particular it's often used when you're querying and using related objects. You'll typically need fast access to specific related objects based on their Ids stored in the records your trigger is processing. Using a Map allows you to index to those records directly rather than iterating through a list, which is very inefficient.
That pattern often looks like this:
Set<Id> myIdSet = new Set<Id>();
for (Contact c : Trigger.new)
myIdSet.add(c.AccountId);
Map<Id, Account> parentAccounts = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet]);
for (Contact c : Trigger.new)
Account accountForThisContact = parentAccounts.get(c.AccountId);
The critical bit is the line
Account accountForThisContact = parentAccounts.get(c.AccountId);
This allows us to immediately access queried Accounts (or any other sObject) by just its Id, with no iteration. Technically speaking, accessing a Map is an O(1) operation, which means it executes in constant time regardless of the number of records in the Map.
edited 1 hour ago
answered 4 hours ago


David Reed
24k41642
24k41642
"unique" isn't exactly right. Maps exist in almost all modern languages.
– sfdcfox
56 mins ago
I was referring to the specific usagenew Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet])
, i.e., passing SOQL results directly into the Map constructor.
– David Reed
54 mins ago
add a comment |Â
"unique" isn't exactly right. Maps exist in almost all modern languages.
– sfdcfox
56 mins ago
I was referring to the specific usagenew Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet])
, i.e., passing SOQL results directly into the Map constructor.
– David Reed
54 mins ago
"unique" isn't exactly right. Maps exist in almost all modern languages.
– sfdcfox
56 mins ago
"unique" isn't exactly right. Maps exist in almost all modern languages.
– sfdcfox
56 mins ago
I was referring to the specific usage
new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet])
, i.e., passing SOQL results directly into the Map constructor.– David Reed
54 mins ago
I was referring to the specific usage
new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :myIdSet])
, i.e., passing SOQL results directly into the Map constructor.– David Reed
54 mins ago
add a comment |Â
up vote
1
down vote
SOQL query returns List
of Sobjects. In current case it returns List
of Accounts.
Map class have constructor, that accepts List
of Sobjects. Map<ID,sObject>(recordList)
. This constructor:
Creates a new instance of the Map class and populates it with the
passed-in list of sObject records. The keys are populated with the
sObject IDs and the values are the sObjects.
as a result of it, in your Map
keys are ids of queried Account
and values are queried Accounts.
The following code snippet illustrates this principle. Try it.
List<Account> accountsList = [
select Id, Name
from Account
];
Map<Id, Account> accountsMap = new Map<Id, Account>(accountsList);
for(Id accountId :accountsMap.keySet())
System.debug('Key:' + accountId + ', value:' + accountsMap.get(accountId));
add a comment |Â
up vote
1
down vote
SOQL query returns List
of Sobjects. In current case it returns List
of Accounts.
Map class have constructor, that accepts List
of Sobjects. Map<ID,sObject>(recordList)
. This constructor:
Creates a new instance of the Map class and populates it with the
passed-in list of sObject records. The keys are populated with the
sObject IDs and the values are the sObjects.
as a result of it, in your Map
keys are ids of queried Account
and values are queried Accounts.
The following code snippet illustrates this principle. Try it.
List<Account> accountsList = [
select Id, Name
from Account
];
Map<Id, Account> accountsMap = new Map<Id, Account>(accountsList);
for(Id accountId :accountsMap.keySet())
System.debug('Key:' + accountId + ', value:' + accountsMap.get(accountId));
add a comment |Â
up vote
1
down vote
up vote
1
down vote
SOQL query returns List
of Sobjects. In current case it returns List
of Accounts.
Map class have constructor, that accepts List
of Sobjects. Map<ID,sObject>(recordList)
. This constructor:
Creates a new instance of the Map class and populates it with the
passed-in list of sObject records. The keys are populated with the
sObject IDs and the values are the sObjects.
as a result of it, in your Map
keys are ids of queried Account
and values are queried Accounts.
The following code snippet illustrates this principle. Try it.
List<Account> accountsList = [
select Id, Name
from Account
];
Map<Id, Account> accountsMap = new Map<Id, Account>(accountsList);
for(Id accountId :accountsMap.keySet())
System.debug('Key:' + accountId + ', value:' + accountsMap.get(accountId));
SOQL query returns List
of Sobjects. In current case it returns List
of Accounts.
Map class have constructor, that accepts List
of Sobjects. Map<ID,sObject>(recordList)
. This constructor:
Creates a new instance of the Map class and populates it with the
passed-in list of sObject records. The keys are populated with the
sObject IDs and the values are the sObjects.
as a result of it, in your Map
keys are ids of queried Account
and values are queried Accounts.
The following code snippet illustrates this principle. Try it.
List<Account> accountsList = [
select Id, Name
from Account
];
Map<Id, Account> accountsMap = new Map<Id, Account>(accountsList);
for(Id accountId :accountsMap.keySet())
System.debug('Key:' + accountId + ', value:' + accountsMap.get(accountId));
answered 4 hours ago


Oleksandr Berehovskiy
8,51521835
8,51521835
add a comment |Â
add a comment |Â
up vote
0
down vote
Records are related to each other using Id
values i.e. one record references another record by having a (foreign key) field that contains the Id
of the other object. Triggers need to be written to handle the "bulk" case - many records at once - because the Salesforce platform puts limits on many operations such as making queries. So it is quite common that while looping over one list of SObjects, you want to find the data for the referenced object. That is where maps come in.
For example:
for (Contact c : Trigger.new)
Account a = acctsWithOpps.get(c.AccountId);
...
where here AccountId
is the foreign key field.
If maps were not used, the code would be more complicated and finding the matching object would be much more costly because the list would need to be looped over to find the match. A map divides up the data added so that a value can be quickly found largely independently of the number of records.
add a comment |Â
up vote
0
down vote
Records are related to each other using Id
values i.e. one record references another record by having a (foreign key) field that contains the Id
of the other object. Triggers need to be written to handle the "bulk" case - many records at once - because the Salesforce platform puts limits on many operations such as making queries. So it is quite common that while looping over one list of SObjects, you want to find the data for the referenced object. That is where maps come in.
For example:
for (Contact c : Trigger.new)
Account a = acctsWithOpps.get(c.AccountId);
...
where here AccountId
is the foreign key field.
If maps were not used, the code would be more complicated and finding the matching object would be much more costly because the list would need to be looped over to find the match. A map divides up the data added so that a value can be quickly found largely independently of the number of records.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Records are related to each other using Id
values i.e. one record references another record by having a (foreign key) field that contains the Id
of the other object. Triggers need to be written to handle the "bulk" case - many records at once - because the Salesforce platform puts limits on many operations such as making queries. So it is quite common that while looping over one list of SObjects, you want to find the data for the referenced object. That is where maps come in.
For example:
for (Contact c : Trigger.new)
Account a = acctsWithOpps.get(c.AccountId);
...
where here AccountId
is the foreign key field.
If maps were not used, the code would be more complicated and finding the matching object would be much more costly because the list would need to be looped over to find the match. A map divides up the data added so that a value can be quickly found largely independently of the number of records.
Records are related to each other using Id
values i.e. one record references another record by having a (foreign key) field that contains the Id
of the other object. Triggers need to be written to handle the "bulk" case - many records at once - because the Salesforce platform puts limits on many operations such as making queries. So it is quite common that while looping over one list of SObjects, you want to find the data for the referenced object. That is where maps come in.
For example:
for (Contact c : Trigger.new)
Account a = acctsWithOpps.get(c.AccountId);
...
where here AccountId
is the foreign key field.
If maps were not used, the code would be more complicated and finding the matching object would be much more costly because the list would need to be looped over to find the match. A map divides up the data added so that a value can be quickly found largely independently of the number of records.
answered 1 hour ago
Keith C
92.6k1087197
92.6k1087197
add a comment |Â
add a comment |Â
up vote
0
down vote
A SOQL query will always return a list of sobjects (only exception will be if using Aggregate queries then it can return an Integer or AggregatQueryResult)
Now There is a constructor for Map that accepts a List, and automatically makes the Sobject Id as its Key.
So the List of SObject can be passed to constuctor, So the single Line code can be written in few lines for Simplification like
List<Account> accList = [SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New];
Map<Id,Account> accountMap = new Map<Id,Account>(accList );
Also you can also get the list back from MAP using
List<Account> accList = accountMap.values();
Src: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_map.htm
"A SOQL query will always return a list of sobjects." Well it is not true actually. It can return also single SObject and Integer
– user1974566
50 mins ago
@user1974566 I agree with aggregate function exception, but it always returns a list. List with 1 element is still a list. Though you can assign it to an individual record it will always be a list.
– Pranay Jaiswal
48 mins ago
add a comment |Â
up vote
0
down vote
A SOQL query will always return a list of sobjects (only exception will be if using Aggregate queries then it can return an Integer or AggregatQueryResult)
Now There is a constructor for Map that accepts a List, and automatically makes the Sobject Id as its Key.
So the List of SObject can be passed to constuctor, So the single Line code can be written in few lines for Simplification like
List<Account> accList = [SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New];
Map<Id,Account> accountMap = new Map<Id,Account>(accList );
Also you can also get the list back from MAP using
List<Account> accList = accountMap.values();
Src: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_map.htm
"A SOQL query will always return a list of sobjects." Well it is not true actually. It can return also single SObject and Integer
– user1974566
50 mins ago
@user1974566 I agree with aggregate function exception, but it always returns a list. List with 1 element is still a list. Though you can assign it to an individual record it will always be a list.
– Pranay Jaiswal
48 mins ago
add a comment |Â
up vote
0
down vote
up vote
0
down vote
A SOQL query will always return a list of sobjects (only exception will be if using Aggregate queries then it can return an Integer or AggregatQueryResult)
Now There is a constructor for Map that accepts a List, and automatically makes the Sobject Id as its Key.
So the List of SObject can be passed to constuctor, So the single Line code can be written in few lines for Simplification like
List<Account> accList = [SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New];
Map<Id,Account> accountMap = new Map<Id,Account>(accList );
Also you can also get the list back from MAP using
List<Account> accList = accountMap.values();
Src: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_map.htm
A SOQL query will always return a list of sobjects (only exception will be if using Aggregate queries then it can return an Integer or AggregatQueryResult)
Now There is a constructor for Map that accepts a List, and automatically makes the Sobject Id as its Key.
So the List of SObject can be passed to constuctor, So the single Line code can be written in few lines for Simplification like
List<Account> accList = [SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New];
Map<Id,Account> accountMap = new Map<Id,Account>(accList );
Also you can also get the list back from MAP using
List<Account> accList = accountMap.values();
Src: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_map.htm
edited 47 mins ago
answered 4 hours ago


Pranay Jaiswal
10.1k31949
10.1k31949
"A SOQL query will always return a list of sobjects." Well it is not true actually. It can return also single SObject and Integer
– user1974566
50 mins ago
@user1974566 I agree with aggregate function exception, but it always returns a list. List with 1 element is still a list. Though you can assign it to an individual record it will always be a list.
– Pranay Jaiswal
48 mins ago
add a comment |Â
"A SOQL query will always return a list of sobjects." Well it is not true actually. It can return also single SObject and Integer
– user1974566
50 mins ago
@user1974566 I agree with aggregate function exception, but it always returns a list. List with 1 element is still a list. Though you can assign it to an individual record it will always be a list.
– Pranay Jaiswal
48 mins ago
"A SOQL query will always return a list of sobjects." Well it is not true actually. It can return also single SObject and Integer
– user1974566
50 mins ago
"A SOQL query will always return a list of sobjects." Well it is not true actually. It can return also single SObject and Integer
– user1974566
50 mins ago
@user1974566 I agree with aggregate function exception, but it always returns a list. List with 1 element is still a list. Though you can assign it to an individual record it will always be a list.
– Pranay Jaiswal
48 mins ago
@user1974566 I agree with aggregate function exception, but it always returns a list. List with 1 element is still a list. Though you can assign it to an individual record it will always be a list.
– Pranay Jaiswal
48 mins ago
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f238595%2fhow-does-class-map-work%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password