You can't refer to properties dynamically like that in Apex.

formSubmission.fs =formSubmissionData.get(fs);

If you want to place a value in the field whose name corresponds to the content of the variable fs, you must use the put() method.

formSubmission.put(fs, formSubmissionData.get(fs));
Answer from David Reed on Stack Exchange
🌐
Mytutorialrack
mytutorialrack.com › home › understanding map methods in apex: key concepts and best practices
Understanding Map Methods in Apex: Key Concepts and Best Practices
June 1, 2023 - Map<String, Integer> studentScores ... // returns false · In Apex, the keySet() method of the Map class returns a Set containing all the keys present in the map....
🌐
Camp Apex
campapex.org › lesson › 640d2a156e4efea481c54de2
Map - Keyset and Values | Camp Apex
This method will return all of the keys in the map as a set that matches the datatype of our keys. Map<String, Decimal> currencyCodeToExchangeRate = new Map<String, Decimal> { 'USD' => 1, 'CAD' => 1.39, 'MXN' => 18.49, 'EUR' => 0.94, 'GBP' => ...
🌐
Reddit
reddit.com › r/salesforce › using maps in apex (beginner)
r/salesforce on Reddit: Using Maps in Apex (beginner)
September 23, 2020 -

I’ve been learning Apex for a little bit now and have a pretty novice understanding of how it all works, but the concept I’m struggling with the most is using maps instead of lists or sets.

Does anyone have good reference material or examples on when Map is useful/what’s really happening in the background? I feel like I’m really close to fully grasping it, but there’s still something missing where I’m not fully understanding the value.

I keep watching tutorials online and they’re definitely inching me closer to a revelation but I’ve failed to find one that really digs in.

Top answer
1 of 5
10
Sounds liek you don't have a grasp of what the differences are. These concepts are not unique to Apex. A list is an ordered sequence of items, like people waiting to get their number called. The thing is, one person can have more than one number assigned, so they can appear in the waiting list more than once. A set is almost like a list except it does not allow for a person to have more than one chance to be in the waiting list (so it only appears once on the whole waiting list) and it's not ordered, so doesn't matter what number the person got assigned to it. A map is a representation of the person waiting and it's number. That number is unique, so it's the key, the person assigned to the number is the value, so each entry of the map is a pair where you can't have two pairs with the same key. Where does it all make sense to use? Well, it depends on the use case. Let's say you want to check all the accounts of all the opportunities to get the account type, the account ID, the name and the opportunity Id and Opp name and export it to a csv so someone somewhere can analyze it. You do your SOQL query, get everything in a nice list and you output it into a nice excel sheet with a pretty header, mail it to the guy that requested it. You come up with this little piece of code: List lstOpp = [Select Id, AccountId, Account.Type from Opportunity]; String output = ''; for(Opportunity opp : lstOpp){ output+=opp.Id+','; output+=opp.AccountId+','; output+=opp.Account.Type+'\n'; } system.debug(output); A day later he replies: "hey! I'm noob at excel and there's duplicates here I don't know how to get rid of. Can you just send it to me without duplicates? Thanks!" You then think: Ok, I'll just add the Opportunities I get from the query and put it into a Set! That way, they get the information they want and no duplicates, right? Right!? Let's see... List lstopp = [Select Id, AccountId, Account.Type from Opportunity]; String output = ''; Set stOpp = new Set(); for(Opportunity opp : lstopp){ stOpp.add(opp); } for(Opportunity opp : stOpp){ output+=opp.Id+','; output+=opp.AccountId+','; output+=opp.Account.Type+'\n'; } system.debug(output); That't not right! My unique value is an opportunity... What I need is to have something that allows me to check if a certain Account is already added on the list I'm writting down on the CSV. Let's however see how this can be done by throwing a Map into the mix :) List lstopp = [Select Id, AccountId, Account.Type from Opportunity]; String output = ''; Map mapOppsByAccountId = new Map(); for(Opportunity opp : lstopp){ /* Notice what happens if you put the same key twice: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_map.htm#apex_methods_system_map */ mapOppsByAccountId.put(opp.AccountId,opp); } for(Id accountId : mapOppsByAccountId.keySet()){ Opportunity opp = mapOppsByAccountId.get(accountId); output+=opp.Id+','; output+=opp.AccountId+','; output+=opp.Account.Type+'\n'; } system.debug(output); Not the best example but I think it helps. If you have more questions (or if I made it even more complicated) let me know.
2 of 5
3
Maps allow you to locate data in a list very easily. Let's say you needed to find a record based on Id. If you just used a list, you would have to iterate through the list using an if statement to find the record with the id that matched your id. With a Map you can simple do a Get statement to return the record with the matching Id. Thinking them as a way to arrange data for easy retrieval later.
Find elsewhere
🌐
Decodeforce
decodeforce.com › blogs › apex-map-class-methods-and-examples
Salesforce apex map class and methods with practice examples
A comprehensive guide on apex map class and methods and how to use them for various data manipulation in salesforce with practice examples.
Top answer
1 of 1
6

Like Adrian mentioned in the comments, it's hard to know how to make your work method "work correctly" when we don't know how the way it's currently working is different from the way you want it to work.

That said, I do have an idea of what may be going wrong (and how to fix it).

First, answering the text of your question the purpose of keySet().contains(<something>) in the following snippet

for(WorkOrder i:newWorkOrder) {
    if(resultMap.keyset().contains(i.ParentWorkOrderId)) {
        WorkOrder wo = resultMap.get(i.ParentWorkOrderId);
        i.related_address__c = wo.Related_Address__c;

        // I've omitted the other lines for brevity
    }                
}

is to make sure that the WorkOrder wo variable inside the if block will never be null. The if statement checks to make sure that your map has an entry for i.ParentWorkOrderId (that the resulting Id exists as a key in the map) before it attempts to use the result of fetching the value in the map for that given key.

A simple example may make things a bit more clear

// This code can be run as anonymous apex through the developer console so that
//   you can verify, for yourself, the assertions I'll be making.

// Declare a simple map that maps one integer to its negative
// What I'm doing here is one way to initialize a map
Map<Integer, Integer> testMap = new Map<Integer, Integer>{
    1 => -1,
    2 => -2
};

// A simple variable to store the result of a .get() from the map
Integer result;

result = testMap.get(1);
// map.containsKey() accomplishes the same thing as map.keySet().contains().
// using containsKey() is more compact, so it is generally preferred.
debug(testMap.containsKey(1));  // This will result in 'TRUE' being printed in the debug log
debug(result);                  // This will result in a '-1' being printed in the debug log

result = testMap.get(2);
debug(testMap.containsKey(2));  // This will result in 'TRUE' being printed in the debug log
debug(result);                  // This will result in a '-2' being printed in the debug log

// We did not make a map entry for the integer 3
result = testMap.get(3);
debug(testMap.containsKey(3));  // This will result in 'FALSE' being printed in the debug log
debug(result);                  // This will result in a 'null' being printed in the debug log

That's all well and good, but what does the if() block in your code actually guard against?

Let's expand the above example just a little more.

Map<Integer, Integer> testMap = new Map<Integer, Integer>{
    1 => -1,
    2 => -2
};

// A simple variable to store the result of a .get() from the map
Integer result = testMap.get(3);

// The format() method of the integer class returns a string representing the 
//   integer in the current user's locale.
// If integer i = 1000, i.format() would return '1,000' in US and UK locales
//   but would return '1.000' in most other locales in the Eurozone (Germany, for example)
system.debug(result.format());

If you try to run that second code example, you'll get a null pointer exception. Why? because 3 isn't a key in the map, and when we try to fetch the value for key 3 from the map, we get null as the result.

The system.debug line effectively becomes system.debug(null.format());. null doesn't have a format() method (it doesn't have any methods). Trying to use dot notation with null results in a null pointer exception.

Getting back to your code now

for(WorkOrder i:newWorkOrder) {
    if(resultMap.containsKey(i.ParentWorkOrderId)) {
        // because we're checking that i.ParentWorkOrderId exists as a key
        //   in resultMap, wo is guaranteed to not be null (well, as long as
        //   the value stored in the map itself isn't null).
        // This means that wo.Related_Address__c is safe to execute (with one caveat).
        WorkOrder wo = resultMap.get(i.ParentWorkOrderId);
        i.related_address__c = wo.Related_Address__c;

        // I've omitted the other lines for brevity (again)
    }
}

So now you know what the purpose of that line is, we can move to getting your code to behave as expected.

Based on your code, it appears that you're depending on the behavior of before triggers to avoid the need to use DML to update the records you're passing in to copyWorkOrderAddress(). This does require a before trigger, and it also requires that you are passing in a list derived _directly from trigger.new (only changes made to the instances stored in trigger.new get auto-updated without DML).

Since you aren't running into a "record is read-only" error (at least, not yet or not that you've indicated), I can assume that this code is being run as part of a before trigger.

If your issue is that your child WorkOrder records aren't getting address values from the parent record, then you should check to see how you're calling your method.

// This should work, because we're directly using trigger.new, and SObjects/
//   collections of SObjects are passed by reference (more or less, it's a bit more
//   complicated than that in reality)
copyWorkOrderAddress(trigger.new);

// This should also work, because the loop variable 'wo' is a reference
//   to the same instance of the work order record that is stored in trigger.new
List<WorkOrder> myList = new List<WorkOrder>();
for(WorkOrder wo :trigger.new){
    if(someCondition){
        myList.add(wo);
    }
}
copyWorkOrderAddress(myList);

// This will not work, because the instance of the work order record we're
//   storing in myOtherList is not a reference to the instance contained in
//   trigger.new, it's a completely independent instance.
List<WorkOrder> myOtherList = new List<WorkOrder>();
for(WorkOrder wo :trigger.new){
    if(someCondition){
        myList.add(new WorkOrker(
            Id = wo.Id, 
            ParentWorkOrderId = wo.ParentWorkOrderId
        ));
    }
}
copyWorkOrderAddress(myList);

Hopefully I was able to identify the issue you're running into. If that isn't it, or you need more specific help, then posting your trigger and trigger handler would be helpful.

One last thing, that caveat I mentioned. As is, your current code doesn't check to see if i.ParentWorkOrderId is null before adding it to your list of Ids to query against. You should be safe in this case, but if you were to actually add null as a key to your map, you could still end up with a null pointer exception (or other fun, odd results could emerge).

When in doubt though, I would add relatedWOID.remove(null); after the loop that populates the relatedWOID set.

🌐
S2 Labs
s2-labs.com › home › map initialization methods in apex
Map Initialization Methods In Apex | Salesforce Developer Tutorials
August 7, 2025 - In Salesforce Apex, Maps are collections of key-value pairs, where each unique key maps to a single value. Initializing of Maps in Apex can be done in various ways depending on the requirements.
Rating: 4.8 ​ - ​ 2.4K votes
🌐
Panther Schools
pantherschools.com › home › salesforce › how to use map collection in salesforce?
How to use Map Collection in Salesforce? » Panther Schools
April 21, 2025 - List<String> ABC = new List<String>(); #1 - Map<String, Integer> accountMap = new Map<String, Integer>(); accountMap.put('Acme', 10000); accountMap.put('XYZ Corp', 5000); accountMap.put('ABC Company', 7500); // Retrieve the value for a specific key Integer acmeValue = accountMap.get('Acme'); System.debug(acmeValue); // Outputs 10000 #2 - Map<String, Integer> accountMap = new Map<String, Integer>{ 'Acme' => 10000, 'XYZ Corp'=> 500 }; Boolean exists = accountMap.containsKey('Acme'); // exists = True accountMap.keySet(); // Returns the Set<Data Type of the Map Key> accountMap.values(); // Returns
🌐
MicroPyramid
micropyramid.com › blog › how-to-use-map-methods-in-salesforce
How to Use Map Methods in Salesforce | MicroPyramid
Ex: Map<String, String> mapname=new Map<String, String>(); mapname.put('red','shirt'); mapname.put('blue','tshirt'); mapname.put('black','shirt'); When the above is executed with both mapname.keyset() and mapname.values() method we will get the values as for keyset:{red, blue, black} for values:{shirt, tshirt, shirt}. From this, we can see that values can be duplicated.
🌐
Salesforce
trailhead.salesforce.com › trailblazer-community › feed › 0D54V00007T4E3dSAF
How to get all keys in Map | Salesforce Trailblazer Community
April 21, 2021 - Skip to main content · Register now for TDX! Join the must-attend event to experience what’s next and learn how to build it
🌐
CRS Info Solutions
crsinfosolutions.com › home › what is a map class in salesforce apex? with examples
What is a Map class in Salesforce Apex? with examples
Salesforce Training
The Map class is a collection type that stores unique keys paired with values. It is used to quickly retrieve, update, or delete data based on a unique identifier, making data handling more efficient and faster than using lists, especially with large data sets. I have enrolled for Salesforce Admin and development online course at CRS info solutions. It’s really the best training i have ever taken and syllabus is highly professional
Rating: 5 ​
🌐
JanbaskTraining
janbasktraining.com › home › salesforce maps: features, benefits & methods
Salesforce Maps: Features, Benefits & Methods
December 29, 2022 - (recordList) - This Map Class constructor generates a new instance of the Map Apex class. Also, this constructor populates it with the sObject records’ passed-in list. The Map keys get populated with the IDs of sObject.
🌐
SFDC Kid
sfdckid.com › 2019 › 04 › salesforce-apex-collection-map.html
APEX COLLECTION: Map - SFDC Kid
I hope you understood the key-value pair concept, from the above example we can say that whenever I am talking about India automatically it's key i.e. Rupee will be considered as its currency. Now unlike list and set, there are attributes for Map as well. Following are the attributes of apex collection Map : clear() : It removes all of the key-value mappings from the map.
🌐
Intellipaat
intellipaat.com › home › blog › what are the map methods available in salesforce?
What are the Map Methods Available in Salesforce? - Intellipaat
April 3, 2025 - An illustration is StateWithCa... the total number of key-value pairs in the map. keySet(): This function returns the set of keys that the map contains....