У меня есть группа индексов, и я хочу удалить элементы в этих индексах из ArrayList
. Я не могу выполнить простую последовательность remove()
, потому что элементы смещаются после каждого удаления. Как это решить?
Удалить несколько элементов из ArrayList
Ответ 1
Сортируйте индексы в порядке убывания, а затем удалите их по одному. Если вы это сделаете, ни один из способов удаления не повлияет на какие-либо индексы, которые вы позже захотите удалить.
Как вы их сортируете, будет зависеть от коллекции, которую вы используете для хранения индексов. Если это список, вы можете сделать это:
List<Integer> indices;
Collections.sort(indices, new Comparator<Integer>() {
public int compare(Integer a, Integer b) {
//todo: handle null
return b.compareTo(a);
}
}
Изменить
@aioobe нашел помощника, которого я не смог найти. Вместо вышесказанного вы можете использовать
Collections.sort(indices, Collections.reverseOrder());
Ответ 2
Чтобы удалить элементы в indexes
:
Collections.sort(indexes, Collections.reverseOrder());
for (int i : indexes)
strs.remove(i);
Или, используя Stream API из Java 8:
indexes.sort(Comparator.reverseOrder());
indexes.stream().mapToInt(i -> i).forEach(l::remove);
Ответ 3
Вы можете удалить элементы, начиная с самого большого индекса вниз, или если у вас есть ссылки на объекты, которые вы хотите удалить, вы можете использовать removeAll.
Ответ 4
Вы можете удалить индексы в обратном порядке. Если индексы порядка 1,2,3, вы можете сделать removeRange (1, 3).
Ответ 5
Я пришел сюда для удаления элементов в определенном диапазоне (т.е. всех элементов между двумя индексами) и нашел это:
list.subList(indexStart, indexEnd).clear()
Ответ 6
Если у вас действительно много элементов для удаления (и длинного списка), может быть быстрее выполнить итерацию по списку и добавить все элементы, которые не должны быть удалены в новый список, поскольку каждый remove()
-ступят в массив-список копирует все элементы после удаления один за другим. В этом случае, если индексный список еще не отсортирован (и вы можете перебирать его параллельно главному списку), вы можете захотеть использовать HashSet или BitSet или некоторую аналогичную O (1) -азретную структуру для contains()
check:
/**
* creates a new List containing all elements of {@code original},
* apart from those with an index in {@code indices}.
* Neither the original list nor the indices collection is changed.
* @return a new list containing only the remaining elements.
*/
public <X> List<X> removeElements(List<X> original, Collection<Integer> indices) {
// wrap for faster access.
indices = new HashSet<Integer>(indices);
List<X> output = new ArrayList<X>();
int len = original.size();
for(int i = 0; i < len; i++) {
if(!indices.contains(i)) {
output.add(original.get(i));
}
}
return output;
}
Ответ 7
закажите свой список индексов, например
если 2,12,9,7,3 порядка до 12,9,7,3,2
а затем сделайте это
for(var i = 0; i < indexes.length; i++)
{
source_array.remove(indexes[0]);
}
это должно решить вашу проблему.
Ответ 8
Если элементы, которые вы хотите удалить, сгруппированы вместе, вы можете выполнить операцию subList(start, end).clear()
.
Если элементы, которые вы хотите удалить, разбросаны, может быть лучше создать новый ArrayList, добавить только те элементы, которые вы хотите включить, а затем скопировать обратно в исходный список.
Изменить: я понимаю, что это не вопрос производительности, а логики.
Ответ 9
Вы можете сортировать индексы так много, или вы можете использовать итератор и вызывать remove()
List<String> list = new ArrayList<String>();
list.add("0");
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
List<Integer> indexes = new ArrayList<Integer>();
indexes.add(2);
indexes.add(5);
indexes.add(3);
int cpt = 0;
Iterator<String> it = list.iterator();
while(it.hasNext()){
it.next();
if(indexes.contains(cpt)){
it.remove();
}
cpt++;
}
это зависит от того, что вам нужно, но сортировка будет быстрее в большинстве случаев
Ответ 10
Используйте guava! Метод, который вы ищете, - Iterators.removeAll(Iterator removeFrom, Collection elementsToRemove)
Ответ 11
вы можете использовать метод subList с диапазоном индекса, который хотите удалить, и затем наберите clear().
(обратите внимание, что последний параметр исключен, и будут удалены только первый и второй элементы):
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> animals = new ArrayList<String>();
animals.add("cow");
animals.add("dog");
animals.add("chicken");
animals.add("cat");
animals.subList(0, 2).clear();
for(String s:animals)
System.out.println(s);
}
}
результат будет: курица кот
Ответ 12
Если вы хотите удалить позиции X в размер
//a is the ArrayList
a=(ArrayList)a.sublist(0,X-1);
Ответ 13
Предполагая, что ваш массив indexes
отсортирован (например: 1, 3, 19, 29), вы можете сделать это:
for (int i = 0; i < indexes.size(); i++){
originalArray.remove(indexes.get(i) - i);
}
Ответ 14
Более эффективный метод, который, я предполагаю, я не видел выше, создает новый Arraylist и выбирает, какие индексы выживают, копируя их в новый массив. И, наконец, переназначьте ссылку.
Ответ 15
Я оказался здесь для аналогичного запроса, и ответ @aioobe помог мне разобраться в решении. Однако, если вы заполняете список индексов для удаления самостоятельно, возможно, захотите рассмотреть возможность использования this:
indices.add(0, i);
Это избавит от необходимости (дорогостоящей) сортировки по переписке списка перед ее итерацией при удалении элементов из основного массива ArrayList.
Ответ 16
Я думаю, что нанда был правильным ответом.
List<T> toRemove = new LinkedList<T>();
for (T t : masterList) {
if (t.shouldRemove()) {
toRemove.add(t);
}
}
masterList.removeAll(toRemove);