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
ahab1372ahab1372 

changing string in a list

I have a piece of code that iterates over a list of strings and changes the strings. Strange thing is that in the end the list has not changed at all, although the modified string is clearly visible in the Debug log within the iteration.

 

I think I know a way around this with a second list, but I am still wondering why it does not work within the list. Don't we do it with sObjects all the time and it works (like iterating over Trigger.New)?

 

code (execute anonymous):

 

		String[] CCAddresses = new string[]{ 'first1.last1@gmail.com','first2.last2@gmail.com'};     
        System.debug('Address List:::::::::::: ' + CCAddresses);

        for (string address:CCAddresses)
        {
        	System.Debug('One Address::::::::::::: ' + address);
        	if(!address.endsWith('@company.com')) 
        	{
        		String newAddress = address + '.full';
        		address = newAddress;
				//address += '.full'; // this doesn't work either
        	}
        	System.Debug('One Address::::::::::::: ' + address);
        }
		
        System.debug('Address List::::::::::::' + CCAddresses);

 

 

Debug Log:

 

Anonymous execution was successful.

18.0 APEX_CODE,FINE;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;VALIDATION,INFO;WORKFLOW,INFO
12:20:13.162|EXECUTION_STARTED
12:20:13.162|CODE_UNIT_STARTED|[EXTERNAL]execute_anonymous_apex
12:20:13.165|METHOD_ENTRY|[3,9]|System.debug(String)
12:20:13.165|USER_DEBUG|[3,9]|DEBUG|Address List:::::::::::: (first1.last1@gmail.com, first2.last2@gmail.com)
12:20:13.165|METHOD_EXIT|[3,9]|debug(ANY)
12:20:13.165|METHOD_ENTRY|[7,10]|System.Debug(String)
12:20:13.165|USER_DEBUG|[7,10]|DEBUG|One Address::::::::::::: first1.last1@gmail.com
12:20:13.165|METHOD_EXIT|[7,10]|debug(ANY)
12:20:13.165|METHOD_ENTRY|[8,14]|String.endsWith(String)
12:20:13.165|METHOD_EXIT|[8,14]|endsWith(String)
12:20:13.165|METHOD_ENTRY|[14,10]|System.Debug(String)
12:20:13.165|USER_DEBUG|[14,10]|DEBUG|One Address::::::::::::: first1.last1@gmail.com.full
12:20:13.165|METHOD_EXIT|[14,10]|debug(ANY)
12:20:13.165|METHOD_ENTRY|[7,10]|System.Debug(String)
12:20:13.165|USER_DEBUG|[7,10]|DEBUG|One Address::::::::::::: first2.last2@gmail.com
12:20:13.165|METHOD_EXIT|[7,10]|debug(ANY)
12:20:13.165|METHOD_ENTRY|[8,14]|String.endsWith(String)
12:20:13.165|METHOD_EXIT|[8,14]|endsWith(String)
12:20:13.165|METHOD_ENTRY|[14,10]|System.Debug(String)
12:20:13.165|USER_DEBUG|[14,10]|DEBUG|One Address::::::::::::: first2.last2@gmail.com.full
12:20:13.165|METHOD_EXIT|[14,10]|debug(ANY)
12:20:13.165|METHOD_ENTRY|[17,9]|System.debug(String)
12:20:13.165|USER_DEBUG|[17,9]|DEBUG|Address List::::::::::::(first1.last1@gmail.com, first2.last2@gmail.com)
12:20:13.165|METHOD_EXIT|[17,9]|debug(ANY)
12:20:13.165|CUMULATIVE_LIMIT_USAGE
12:20:13.165|LIMIT_USAGE_FOR_NS|(default)|

 

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
stwdevstwdev

From the Apex documentation:

 

Iterating Collections

Collections can consist of lists, sets, or maps. Modifying a collection's elements while iterating through that collection is not supported and causes an error. Do not directly add or remove elements while iterating through the collection that includes them.

All Answers

stwdevstwdev

From the Apex documentation:

 

Iterating Collections

Collections can consist of lists, sets, or maps. Modifying a collection's elements while iterating through that collection is not supported and causes an error. Do not directly add or remove elements while iterating through the collection that includes them.

This was selected as the best answer
ahab1372ahab1372

that says it all ... Thanks for clarifying.

I actually read this page in the documentation but did not see this sentence, probably because there is no heading. Or I just need to pay better attention :-) My bad.

 

Obviously I never manipulated primitive collections before (at least I don't remember), and for sObjects collections it works fine.

Example from Apex documentation:

http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_triggers_context_variables.htm

 

Trigger Context Variables

 

 

for (Account a : Trigger.new) {
            System.assertEquals('xxx', a.accountNumber); 
            System.assertEquals('industry', a.industry); 
            System.assertEquals(100, a.numberofemployees);
            System.assertEquals(100.0, a.annualrevenue);
            a.accountNumber = 'yyy';
}

 

 

bob_buzzardbob_buzzard

It works with sobjects as long as you aren't changing the sobject reference that is stored in the collection - i.e. replacing an  object in the list with another, which is effectively what you are doing with primitives.

 

The example from the docs is changing a field on the object stored in the list, but leaving the object reference alone.

JieMeJieMe

this case,how to update the field value of list in loop?

 

thanks!

bob_buzzardbob_buzzard

You can't really - you have to find the old version and remove it, then add the new version.

 

An alternative is to store wrapper class instances in the list, that contain a single string property.  Then you can change the string without affecting the wrapper class instance.