15

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
    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 '15 at 0:50
  • Do you have a reference for this? – mkorman Jul 16 '15 at 11:27
13

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;
}
  • question: if target's objects and toRemove are custom types, do they have to implement an equals() and hashcode() method? – cropredy Nov 1 '18 at 17:19
  • @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. – Alex Tennant Nov 8 '18 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);
  • 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 '15 at 20:50
-1

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);
    }
}
  • 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 '15 at 16:00
  • No, it will succeed. – Ceez Jun 24 '15 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 '15 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 '15 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 '15 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.