Given a set of positions, Set<Integer> positionsToRemove
, I'd like to remove all items from a list, List<?> list
, that their position correspond to the values in the set.
public static void remove(List<?> list, Set<Integer> positionsToRemove) {
// ?
}
Notes:
You must ensure to remove items in reverse , as otherwise the indices will become invalid.
You can do this very easily with a List
:
public static void remove(List<?> list, Set<Integer> positionsToRemove) {
final ListIterator<?> iter = list.listIterator(list.size());
while (iter.hasPrevious()) {
iter.previous();
if (positionsToRemove.contains(iter.nextIndex())) {
iter.remove();
}
}
}
This takes advantage of the ability if ListIterator
to provide the current index and also it's ability to iterate in reverse.
It also does not rely on a "marker value" so null
is allowed in the input List
.
Obviously you could do this much more simply with an "old style" indexed loop:
public static void remove(List<?> list, Set<Integer> positionsToRemove) {
for (int i = list.size() - 1; i >= 0; --i) {
if (positionsToRemove.contains(i)) {
list.remove(i);
}
}
}
But it should be noted that if the List
lacks RandomAccess
this will be O(n^2)
, whereas the ListIterator
based solution would be O(n)
for a List
that has O(1)
remove
.
It may be quicker to return a new List
, depending on how may elements you are removing and also the type of the List
- for an ArrayList
the remove
operation is quite expensive:
public static <T> List<T> remove(List<T> list, Set<Integer> positionsToRemove) {
return IntStream.range(0, list.size())
.filter(i -> !positionsToRemove.contains(i))
.mapToObj(list::get)
.collect(toList());
}
public static void remove(List<?> list, Set<Integer> positionsToRemove) {
for (Integer position : positionsToRemove) {
list.set((int)position, null);
}
for (Iterator<?> iterator = list.iterator(); iterator.hasNext(); ) {
Object o = iterator.next();
if (o == null) iterator.remove();
}
}
public static void remove(List<?> list, Set<Integer> positionsToRemove) {
int i = 0;
for (Iterator<?> iterator = list.iterator(); iterator.hasNext(); ++i) {
iterator.next();
if (positionsToRemove.contains(i)) iterator.remove();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.