Как удалить определенные элементы коллекции с учетом сдвига
Есть коллекция, состоящая из интовых чисел, и в ней нужно удалить чётные элементы.
Я попытался сделать это через цикл, но когда я удаляю элемент, индексы сдвигаются, и пропускается одно число, и получается, если все числа четные, то удаляются элементы через одного.
import java.util.ArrayList;
import java.util.List;
public class col {
public static void main(String[] args) {
List nums = new ArrayList<>();
nums.add(2);
nums.add(4);
nums.add(6);
nums.add(8);
nums.add(2);
nums.add(10);
nums.add(22);
nums.add(12);
print(nums);
for (int i = 0; i < nums.size() - 1; i++) {
if ((Integer) nums.get(i) % 2 == 0) {
nums.remove(i);
}
}
System.out.println("");
print(nums);
}
public static void print(List list) {
for (int i = 0; i < list.size() - 1; i++) {
System.out.print("[" + list.get(i) + "]");
}
}
}
Ответы (3 шт):
Я понял как это сделать, просто добавить проверку, похожую на сортировку пузырьком
import java.util.ArrayList;
import java.util.List;
public class col {
public static void main(String[] args) {
List nums = new ArrayList<>();
nums.add(2);
nums.add(4);
nums.add(6);
nums.add(8);
nums.add(2);
nums.add(10);
nums.add(22);
nums.add(12);
print(nums);
boolean norm = false;
while (!norm) {
norm = true;
for (int i = 0; i <= nums.size() - 1; i++) {
if (((Integer) nums.get(i) % 2) == 0) {
norm = false;
nums.remove(i);
}
}
}
print(nums);
}
public static void print(List list) {
for (int i = 0;i<list.size()-1;i++){
System.out.print("["+list.get(i)+"]");
}
}
}
Можешь изменять значения на null, а в методе print если объект == null то его не выводить.
Наиболее простой/лаконичный современный (Java 8+) способ удаления элементов из коллекции -- использовать метод Collection::removeIf, в который следует передать функцию-предикат для определения удаляемых элементов. Также для проверки на чётность можно проверять младший бит на равенство 0:
List<Integer> data = new ArrayList<>(Arrays.asList(2,3,4,6,8,10,22,-2,-5,0));
data.removeIf(n -> (n & 1) == 0); // [3, -5]
Упомянутый метод использует под капотом итератор и его метод Iterator::remove, который как раз рекомендуется для безопасного удаления элементов из коллекции при прохождении по ней, так как позволяет избежать излишних сложностей с индексной арифметикой и проблем с ConcurrentModificationException со времён Java 1.2 и появления Collection Framework.
List<Integer> data = new ArrayList<>(Arrays.asList(2,3,4,6,8,10,22,-2,-5,0));
for (Iterator<Integer> it = data.iterator(); it.hasNext();) {
if (0 == (it.next() & 1)) {
it.remove();
}
}
Однако если стоит задача реализовать удаление именно с использованием индексов, можно удалять элементы с конца, согласно совета в комментариях:
for (int i = data.size(); i-- > 0;) {
if (data.get(i) % 2 == 0) {
data.remove(i);
}
}
Если же и такой вариант -- недопустимая хитрость, и нужен классический for цикл по индексам именно с начала списка, то коррекцию индексов и размера списка можно выполнить так:
for (int i = 0, n = data.size(); i < n; i++) {
if (data.get(i) % 2 == 0) {
data.remove(i--); // коррекция индекса при удалении
n--; // коррекция размера списка
}
}