function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Greg RohmanGreg Rohman 

Unexplainable nested map/list behavior - picking up values from last Map entry?

Hello.

 

I was hoping someone could shed some light onto my problem. I have a Map that contains a String as the key, and a List of custom objects as the value, as follows:

 

private Map<String,List<Title_Deal__c>> mainUserDealMap = new Map<String,List<Title_Deal__c>>();

 I have some logic in my code where I'm looping on a list of users, and if certain criteria match, I'm adding the Title_Deal__c to the map, along with the user's first and last name as the key. The code is below:

 

 

        // Loop on each user
        for (user u: userListForWrapper) {
            // Clear variables
            groupIdTemp.clear();
            salespersonIdTemp.clear();
            dealIdTemp.clear();
            tempUserDealList.clear();

            // find all groups that each user belongs to, and store the group Id
            for (GroupMember gm: groupMemberListTemp) {
                if(gm.UserOrGroupId == u.Id) {
                    groupIdTemp.add(String.valueOf(gm.GroupId).substring(0,15));
                }
            }  
            //Determine which Salesperson__c contain that group ID, and store the salesperson Id
            for (Salesperson__C sp: salespersonListTemp) {
                if(groupIdTemp.contains(sp.Group_Id__c)) {
                    salespersonIdTemp.Add(sp.Id);
                }
            }

            // Loop on deals
            for (Title_Deal__c deal: dealListTemp) {
                if(salespersonIdTemp.contains(deal.Salesperson__c)) {
                    // Add the deal to a temp list, to be added to the main salesperson/deal map
                    tempUserDealList.Add(deal);
                }
            }

    
            // Add the list of deals to the main salesperson/deal map, with the name as the key
            string tempName = u.FirstName + ' ' + u.LastName;
            mainUserDealMap.put(tempName,tempUserDealList);

            system.debug('tempname=' + tempName + ', deals=' + tempUserDealList);
            system.debug('map=' + mainUserDealMap.get(tempName));
        }

 

 

Everything up to that point works fine. When I view the system log output from the two debug statements at the end, they match, as they should.

 

The problem is when I do anything with the map outside of the user loop. I add the following line (where "John Doe" is a valid key name) just outside of the user loop:

 

 

        system.debug('testmap2=' + mainUserDealMap.get('John Doe'));

 

Instead of returning the actual list of Title_Deal__c records that are actually assigned to the "John Doe" key, it's returning one of the other lists, assigned to another key. It appears that it returns the List from the last item entered into the Map, as opposed to the List at the key I've requested.

 

 

Any guidance or assistance would be greatly appreciated. Thank you in advance.

 

-Greg

 

 

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

I suspect this is because you are re-using the same list objects, just clearing them each time through the loop.  This means that each entry in the main user detail map has the same value - the single instance of tempUserDealList that you are re-using.

 

Instead of : 

 

 

tempUserDealList.clear();

 

 

try:

 

 

tempUserDealList=new List<Title_Deal__c>();

 

This will create a new instance of the list each time through the loop, which appears to be what you want.  The same applies to the other variables.

 

 

 

All Answers

bob_buzzardbob_buzzard

I suspect this is because you are re-using the same list objects, just clearing them each time through the loop.  This means that each entry in the main user detail map has the same value - the single instance of tempUserDealList that you are re-using.

 

Instead of : 

 

 

tempUserDealList.clear();

 

 

try:

 

 

tempUserDealList=new List<Title_Deal__c>();

 

This will create a new instance of the list each time through the loop, which appears to be what you want.  The same applies to the other variables.

 

 

 

This was selected as the best answer
Greg RohmanGreg Rohman

Hi Bob.

 

Thanks for the quick reply. That worked! I don't quite understand why, though. Why wouldn't the clear() method remove all of the elements from my lists/sets, essentially doing the same thing?

 

Again, thanks.

 

-Greg

bob_buzzardbob_buzzard

That will remove the elements from your list, but still retain the reference to the list.  Thus each entry in the map has a value with the same reference and therefore is pointing at the same list, so when you clear it, it is cleared for all.

 

When you create a new list each time through the loop, each entry has a value with a different reference and therefore is pointing at a different list.  If you were to clear one of these, all the other entries would remain unaffected.