0

In my programm I have a List of Strings and a List of integer values which should be deleted from the first list. Think of somehing like this:

ArrayList<String> items = new ArrayList<String>();
items.add("A"); items.add("B"); items.add("C");

ArrayList<Integer> del = new ArrayList<Integer>();
del.add(1); del.add(2);

Of course I can loop throught the list with this code and delete the items:

for (int i = 0; i < del.size(); i++) 
{
    items.remove(del.get(i));
}

But here is the problem. After the first element is deleted the index is shifted so I delete the wrong items. Is there a graceful solution for this?

6
  • 6
    Delete in reverse order, remove the higher indices first. Commented Feb 25, 2014 at 12:59
  • 4
    what is this ArrayList<Integer> del = new ArrayList<String>(); Commented Feb 25, 2014 at 13:00
  • Of course you are right. Thanks for that. So easy solution... Commented Feb 25, 2014 at 13:01
  • ArrayList<Integer> del = new ArrayList<String>(); <-- this will not compile Commented Feb 25, 2014 at 13:01
  • what about checking the item's value? Commented Feb 25, 2014 at 13:02

3 Answers 3

3

Sort the deletion list in a descending order and then iterate:

Collections.sort(del, Collections.reverseOrder());
for (Integer toDelete : del) {
    // casting to int, because you need #remove(int), not #remove(Object)
    items.remove((int)toDelete);
}

[edit] Fixed. Sorry, this was twice reversed at the beginning.

[edit2] Added necessary cast :)

Sign up to request clarification or add additional context in comments.

3 Comments

Great answer, didn't think of that. Also, please note my answer about using a problem domain key instead of the index.
Question to edit2: Shouldn't Java pack/unpack the wrapper by itself?
No, as there is also a #remove(Object) method, this one has precedence, if not casting explicitly; the #remove(Object) method would try to remove an Object from the list, for which equals(Object) is true; #remove(int) on the other hand removes by index, which is what you want.
1

You have a few options, but two of the simpler ones are:

  1. Delete the largest indices first. Sort your index list in descending order before you do this.

  2. If sorting the index list is not feasible for some reason and your string list doesn't usually contain null, first replace all the items you want to delete with null then remove all nulls from the string list (e.g. while (items.remove(null)) ;).

Comments

0

Graceful? I don't think so. A working solution would be to make sure your del list is sorted and then go through and decrement all following indexes so they sync back up.

A better solution would be to use a key that is endemic to the problem domain for your deletes instead of the index into the array. That would be a graceful solution.

1 Comment

Your suggestion about the key is a good one. However, for the first idea, the indexes wouldn't need to be sync'd if the index list was sorted in descending order.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.