19

I'm studing apex now and dont understand the situation with list and iterator. In java you cant delete in any way elements from list while iterating it. So therefore developers added iterator and also added removeAll method to list. Here are some examples.

Deleting element by using another list in java:

    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);

    List<Integer> listToRemove = new ArrayList<Integer>();

    for (Integer num : list) {
        if (num==1){
            listToRemove.add(num);
        }
    }

    list.removeAll(listToRemove);
    System.out.println(list);

Result: [2, 3]

Deleting element by using iterator in java:

    Iterator<Integer> iterator = list.iterator();

    while(iterator.hasNext()){
        if(iterator.next() == 1){
            iterator.remove();
        }
    }
    System.out.println(list);

Result: [2, 3]

Ok, then i decided to do the same on apex.

Firstly, i didn't find removeAll method for list. Bad luck :)

Then i found iterator and thought that logic is the same as in java, but got this:

Method does not exist or incorrect signature: [Iterator].remove()

Almost the same, they kept hasNext(), next(), but they did not keep a remove() method. Why? :)

Then i tried to do something like this:

Iterator<Integer> iter = li.iterator();   Integer count = 0;

while(iter.hasNext()){
    Integer temp = iter.next();    
    if(temp == 1){
        li.remove(count);
    }
    count++;   
}   
System.debug(li);

It doesn't work also.

So the only way that works for me is:

    for (Integer i = 0; i < li.size(); i++) {
        if (li.get(i) == 1){
            li.remove(i);
            i--;
        }
    }

Can you please share with me with the best way of removing elements form list!? Thanks in advance!

2
  • 2
    Internally the List<T> in Apex is a Java ArrayList type which is a resizable array. When you remove an item from the array, the entire collection shifts left (one position removed from the element indices).
    – Mark Pond
    Jun 10, 2015 at 0:50
  • Do you have a reference for this?
    – mkorman
    Jul 16, 2015 at 11:27

3 Answers 3

22

The idiomatic way to do this in other languages without iterator semantics is to iterate through the list backwards.

For example:

public static List<Object> removeAll(List<Object> target, Object toRemove) {
    for(Integer i = target.size() - 1; i >= 0; i--) {
        if(target[i].equals(toRemove)) {
            target.remove(i);
        }
    }

    return target;
}
2
  • question: if target's objects and toRemove are custom types, do they have to implement an equals() and hashcode() method?
    – cropredy
    Nov 1, 2018 at 17:19
  • 1
    @cropredy Yes and no. Ideally yes though. If you don't implement them it will only remove things if they are the same object in memory. Nov 8, 2018 at 22:43
1

I don't know if it's a best practice, but one way to reverse your approach and make a second list of the items you want to keep, then once you're done iterating, reassign that to your primary list.

So, using your code, it would be:

    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);

    List<Integer> listToKeep = new ArrayList<Integer>();

    for (Integer num : list) {
        if (num != 1){
            listToKeep.add(num);
        }
    }

    list = listToKeep;
    System.out.println(list);
1
  • this one is only good if we don't have a huge list, because then we will do add operation many times, but thanks anyway. So there is no "special" apex method or style for manipulation with list?!
    – Bogdan K
    Feb 8, 2015 at 20:50
-3

If the List doesn't have to have duplicates, you can convert to Set and use remove method on the Set.

List<Integer> listOfInts = new List<Integer>();
Set<Integer> setOfInts = new Set<Integer>(listOfInts);

for(Integer i : setOfInts) {
    if(i == 1) {
        setOfInts.remove(i);
    }
}
6
  • 2
    Your code will actually error when you try to remove things from a set you are iterating through and won't work.
    – dphil
    Jun 23, 2015 at 16:00
  • No, it will succeed.
    – Ceez
    Jun 24, 2015 at 6:58
  • it doesnt work, because we cant use variable names like: list, set.. Because code in apex is case insensitive
    – Bogdan K
    Jun 24, 2015 at 16:15
  • Yes, as for name you are right (it's just an example), but the logic is fine and works correctly.
    – Ceez
    Jun 25, 2015 at 7:41
  • 1
    Have you tried that logic? You cannot remove something from a collection as you are iterating through it.
    – dphil
    Jun 25, 2015 at 17:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .