Фильтрация списка пользователей in-place

20. Отфильтровать список пользователей in-place

Условие задачи:
Дан изменяемый список ArrayList<User>.

Необходимо реализовать метод filterUsers(), который изменяет исходный список in-place, оставляя только пользователей, у которых:

  • имя начинается с namePrefix;

  • возраст строго больше 18.

Создавать новый список не требуется.

Код:

@Data
class User {
    private String name;
    private int age;
}

public class UserUtils {

    public static void filterUsers(
            ArrayList<User> users,
            String namePrefix
    ) {
        // ваш код
    }
}

Спойлеры к решению

Подсказки
💡 Поскольку список нужно изменить in-place, можно использовать removeIf().
💡 Удалять нужно пользователей, которые не удовлетворяют хотя бы одному из условий.
💡 Для проверки имени используй startsWith(namePrefix).
💡 Пользователь остаётся только при age > 18.

Решение

Самый простой вариант:

public static void filterUsers(
        ArrayList<User> users,
        String namePrefix
) {
    users.removeIf(user ->
            !user.getName().startsWith(namePrefix)
                    || user.getAge() <= 18
    );
}

Оставить пользователя нужно, если одновременно выполняются два условия:

user.getName().startsWith(namePrefix)
        && user.getAge() > 18

Следовательно, удалить нужно всё, что этому условию не соответствует:

!user.getName().startsWith(namePrefix)
        || user.getAge() <= 18

removeIf() изменяет исходный список, поэтому дополнительная коллекция не создаётся.

Альтернативный вариант через Iterator:

public static void filterUsers(
        ArrayList<User> users,
        String namePrefix
) {
    Iterator<User> iterator = users.iterator();

    while (iterator.hasNext()) {
        User user = iterator.next();

        if (!user.getName().startsWith(namePrefix)
                || user.getAge() <= 18) {
            iterator.remove();
        }
    }
}

Для ArrayList предпочтительнее removeIf(): он не только короче, но и позволяет удалить подходящие элементы более эффективно, чем последовательные Iterator.remove(), которые могут многократно сдвигать элементы массива.