Azog the Debugger
Azog the Debugger

Reputation: 227

Java ArrayList.removeAll(), but for indices

Is there a way to do something like this:

ArrayList<String>.removeAll(ArrayList<Integer>)

With the ArrayList<Integer> being the indices that I want deleted. I know that I could iterate through the indices list and use remove(index), but I was wondering if there is a one-command way of doing so.

I know how to put this iteration into one line, my question is, if there is a way implemented by oracle.

Upvotes: 7

Views: 3046

Answers (3)

John Purnell
John Purnell

Reputation: 140

I still get warnings with the above by @rgettman. To avoid the warnings and to make sure you are using the right remove method you can do this. I know some people hate lambdas but I think this is clearer than the extra mapToInt

    public void removeIndices(List<OtherObject> other, List<Integer> indices)
    {
       indices.stream()
             .sorted(Comparator.reverseOrder())
             .forEach(i->other.remove(i.intValue()));
    }  

Upvotes: 0

Eran
Eran

Reputation: 393801

You can use Java 8 Streams.

For example:

IntStream.of(7,6,5,2,1).forEach(i->list.remove(i));

If the indices are given as a List<Integer>, you can do:

indexList.stream().mapToInt(Integer::intValue).forEach(i->list.remove(i));

Note that I preferred to use an IntStream and not a Stream<Integer>, since if you use a Stream<Integer> for the indices, if the list from which you wish to remove elements is itself a List<Integer>, calling remove(Integer) will remove the element whose value is that Integer, not the element whose index is that Integer.

Upvotes: 3

rgettman
rgettman

Reputation: 178263

You can use a Stream to iterate through the indices to remove. However, take care to remove the highest index first, to avoid shifting other elements to remove out of position.

public void removeIndices(List<String> strings, List<Integer> indices)
{
     indices.stream()
         .sorted(Comparator.reverseOrder())
         .forEach(strings::remove);
}

For removing from a list of Strings this will work, calling the proper remove(int) method. If you were to try this on a List<Integer>, then you will have to avoid calling remove(E) by calling .mapToInt(Integer::intValue) before calling forEach.

Upvotes: 5

Related Questions