Apex collections are always passed by reference meaning that it is just a pointer to the original collection. If you want to create a new instance of a collection that can be independently modified you will want to use the clone() method on the collection. More information is available at https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_set.htm

Answer from dsharrison on Stack Exchange
🌐
Reddit
reddit.com › r/salesforce › iterate through list and remove items
r/salesforce on Reddit: Iterate through list and remove items
April 23, 2014 -

Does anyone have a code example of how to iterate through a list and remove any list items that match the items in another list? So, say I have a list of CDs and a list of LPs, I want to look through the list of CDs and remove any that are for the same artist and album as an item in the list of LPs. I'm thinking I'm probably going to need a map but I've never written a map before and can't seem to find any examples of them that remove things.

UPDATE: Thanks for all the input guys. I'm totally going to save this thread and use all this stuff in the future. As for the current scenario. I found a different solution. I was attempting to avoid an error message but the client actually wants to see the error message SO totally different scenario :)

Top answer
1 of 3
2

I'd convert your list to sets, and use set.contains, and set.removeAll. Check out the set docs.

https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_set.htm#apex_System_Set_methods

I'd do it like this (provided I am understanding your question). it could be a set of anything, I'm just using Ids since I don't know what your data type is. You could the convert the set back into a list if you need. Or you can use the suggestion below of iterating the list, recording the index position (which might be a pain/inefficient to get since lists don't have a contains method, so you'd need to iterate and search the list for every element).

//set created from your first list, Im calling it listA (provided your list is a list of ids)
set<id> firstSet = new set<id>(listA);

//set created from your second list, which I'm calling listB (provided your list is a list of ids)
set<id> secondSet = new set<id>(listB);

//temp variable to hold the things to delete
list<id> thingsToRemove = new list<id>();

//iterate the first set
for(id thisId : firstSet)
{
    //see if this thing is in the second set
    if(secondSet.contains(thisId))
    {
	    //if so, then add it to our list of things to remove
	    thingsToRemove.add(thisId);
    }
}

//remove the things from the set
firstSet.removeAll(thingsToRemove);
2 of 3
1

Edit: Just realized that if you are actually storing albums as sObjects and can retrieve with SOQL, none of this is necessary. It would be one line:

List<Album> filteredCDs = [ Select Id, Name... etc from Album Where Id in : CDs and Id Not in : LPs ];

Given that, I bet all my assumptions were wrong, eh? Perhaps I should have asked more questions, but hey, nothing like writing a novel about code... while at work... supposedly working on work related code...


The problem with lists is you can only remove items by passing an index. Once it's removed, the indeces are reset, so it's pretty much impossible to iterate through a list and remove items while you're in the same loop.

Here's how I'd do it without maps (and by making big assumptions about your existing code):

private List<Album> filterCDs(List<Album> CDs, List<Album> LPs) {

    List<Album> filteredCDs = new List<Album>();

    for ( Album CD: CDs) {
        for ( Album LP : LPs ) {
            if ( LP.ArtistName != CD.ArtistName && LP.AlbumName != CD.AlbumName )
                filteredCDs .add(CD);
        }
    }

    return filteredCDs;
}

So this doesn't actually remove anything, it just only returns the cds that don't appear in the LP list. If your lists are large, this is crazy inefficient though, with the number of comparisons being CDs.size() * LPs.size().

Maps are not as scary as they seem, and are extremely useful! They're basically the same as a list/array, but can use an index other than an integer. What's cool about maps is you can build one with SOQL, and it gives you a kind of list where each index is the ID of the record.

Here's how I'd do it with a map (assuming albums are an sObject and not just a Class):

private List<Album> filterCDs(List<Album> CDs, List<Album> LPs) {

    Map<Id, Album> LPMap = new Map<Id, Album>([ Select Id from Album where Id in : LPs ]);

   /*
    ^ returns a kind of list where the indexes are the Ids of each record, like:

        LPMap = {
            'albumid0' = Album{
                Id = 'albumid0'
            },
            'alumbid1' = Album{
                Id = 'albumid1'
            },...
        }
    */

    List<Album> filteredCDs = new List<Album>();

    for ( Album CD: CDs) { // iterate through CDs
        if ( !LPMap.containsKey(CD.Id) ) // if the LP map does *not* contain this CD id
            filteredCDs.add(CD); // add it to the new list
    }

    return filteredCDs;
}

Calling LPMap.containsKey(some_album_id) is better than iterating through the entire list and physically checking if an album with the same title/artist is present. It's similar to checking whether or not LPMap.get(some_album_id) == null. And now the number of comparisons is just the size of the CDs list.

Definitely find more info about maps and how to build them manually with .put(key, value). Removing is just .remove(key).

Anyway, hope that makes some amount of sense... I'd have to know more about how you're already organizing things to know whether or not everything I've just typed is utterly useless or not!

Discussions

apex - how to remove members of a list from a set - Salesforce Stack Exchange
I have a Set made up of group members - but it includes members who are managers of group members. I thought I could iterate over the set and for each member of the group query the user object man... More on salesforce.stackexchange.com
🌐 salesforce.stackexchange.com
Feed Item Detail | Salesforce Trailblazer Community
🌐 developer.salesforce.com
December 22, 2020
apex - RemoveAll on set of records before insert doesn't remove matching records in set of existing records - Salesforce Stack Exchange
I've run into an issue comparing sets of records to insert vs sets of records that already exist as the set of existing records contains a record ID and therefore the removeAll method doesnt see a ... More on salesforce.stackexchange.com
🌐 salesforce.stackexchange.com
March 7, 2016
apex - Best way to remove element from list or why they kept iterator without this option - Salesforce Stack Exchange
it doesnt work, because we cant ... list, set.. Because code in apex is case insensitive ... Yes, as for name you are right (it's just an example), but the logic is fine and works correctly. ... Have you tried that logic? You cannot remove something from a collection as you are iterating through it. ... Find the answer to your question by asking. Ask question ... See similar questions with these tags. ... 2 RemoveAll on set of ... More on salesforce.stackexchange.com
🌐 salesforce.stackexchange.com
June 23, 2015
People also ask

Are Apex Set elements case-sensitive for Strings?
Yes. For a Set, 'VIP' and 'vip' are treated as two distinct elements, so both can coexist in the same Set. If you want case-insensitive uniqueness, normalise the case (for example with toLowerCase()) before adding values to the Set.
🌐
micropyramid.com
micropyramid.com › home › blog › salesforce › apex set methods in salesforce: a complete guide
Apex Set Methods in Salesforce: A Complete Guide | MicroPyramid
What is a Set in Salesforce Apex?
A Set is an Apex collection that holds an unordered group of unique elements. It never stores duplicates, so adding a value that already exists has no effect. Sets are optimised for membership tests with contains() and are the standard tool for de-duplication and for collecting distinct record Ids.
🌐
micropyramid.com
micropyramid.com › home › blog › salesforce › apex set methods in salesforce: a complete guide
Apex Set Methods in Salesforce: A Complete Guide | MicroPyramid
What is the difference between a Set and a List in Apex?
A List is ordered, allows duplicates, and is accessed by a zero-based index. A Set is unordered, stores only unique values, and has no index access - you test membership with contains() instead of get(i). Use a List when order or duplicates matter (such as SOQL results), and a Set when you need uniqueness, like collecting distinct Account Ids.
🌐
micropyramid.com
micropyramid.com › home › blog › salesforce › apex set methods in salesforce: a complete guide
Apex Set Methods in Salesforce: A Complete Guide | MicroPyramid
🌐
Salesforce
ideas.salesforce.com › s › idea › a0B8W00000Hk5yjUAB
Add removeAll() and retainAll() methods to Maps | IdeaExchange
For example, this is how ... work similarly): removeAll(listOfKeysToRemove) Removes the mappings for the keys specified in the list from the map if they are present ·...
🌐
Stack Exchange
salesforce.stackexchange.com › questions › 113291 › removeall-on-set-of-records-before-insert-doesnt-remove-matching-records-in-set
apex - RemoveAll on set of records before insert doesn't remove matching records in set of existing records - Salesforce Stack Exchange
March 7, 2016 - The best solution I've found is to run the list of collaborationgroupmembers through a FOR loop to create a new list that does not contain the Id field, and use that in the removeAll method. set <collaborationGroupMember> cgmembersNoId = new set <collaborationGroupMember>(); FOR (collaborationGroupMember cgm : cgmembers){ collaborationGroupMember cgmx = new collaborationGroupMember(); cgmx.MemberId = cgm.MemberId; cgmx.CollaborationGroupId = cgm.CollaborationGroupId; cgMembersNoId.add(cgmx); }
Find elsewhere
🌐
MicroPyramid
micropyramid.com › home › blog › salesforce › apex set methods in salesforce: a complete guide
Apex Set Methods in Salesforce: A Complete Guide | MicroPyramid
June 10, 2026 - Core methods: add, addAll, remove, removeAll, retainAll, contains, containsAll, clear, isEmpty, size, clone, equals. The #1 use is collecting a Set<Id> and binding it into SOQL as WHERE Id IN :idSet - one query for many records, instead of querying inside a loop.
🌐
Salesforce
trailhead.salesforce.com › trailblazer-community › feed › 0D54V00007T4MZqSAN
Removing a List of values from set in apex? - Trailhead
June 10, 2016 - Skip to main content · Scheduled Maintenance: Trailhead, myTrailhead, and Trailblazer Community will be offline January 17, 16:00–20:00 UTC. Thanks for bearing with us as we update your experience
🌐
https://s2-labs.com/
shreysharma.com › home › sets initialization and methods
Sets Initialization Methods | Salesforce Training - S2 Labs
August 7, 2025 - In Salesforce Apex, initializing a Set can be done in several ways depending on whether you want the Set to be empty initially or pre-filled with values. The way you declare sets is similar to the way you declare lists.
🌐
C# Corner
c-sharpcorner.com › home › technologies › salesforce › apex set in salesforce
Apex Set In SalesForce
September 12, 2019 - A set is an unordered collection of elements that do not contain any duplicates. Set elements can be of any data type—primitive types, collections, sObjects, user-defined types, and built-in Apex types.
🌐
JanBask Training
janbasktraining.com › home › how to create list in salesforce and set methods: to ensure a bright career
How to Create List in Salesforce and Set Methods: To Ensure A Bright Career
July 9, 2024 - Set methods in Salesforce comprise of apex set class, which is responsible for collecting unique components where no duplicates of the object values are allowed. Using numerous ways, you can extend the Apex sales class.
🌐
Apex Hours
apexhours.com › home › salesforce release notes › preventing collection modification during iteration in apex (set) – winter’25 release
Preventing Collection Modification During Iteration in Apex (Set) - Winter’25 Release - Apex Hours
October 14, 2024 - In Apex, modifying a Set while iterating over it was previously allowed, but it often led to unpredictable behavior. Developers encountered issues such as skipped elements, multiple processes on the same element, or unexpected errors. To address this, from API version 61.0, Apex introduced a restriction that prevents modifying a Set during iteration.