Java: удалить один объект из списка, который находится в списке

#java #filter #java-stream

#java #Фильтр #java-поток #java-stream

Вопрос:

Привет, у меня есть список пользователей, у которых может возникнуть несколько вопросов. На каждый вопрос может быть несколько ответов. Я хочу отфильтровать неправильные. Я пробовал приведенный ниже код, но фильтр не работает. Я хочу знать, почему

 Users.stream().forEach(user ->
            user.getAnswers().stream().forEach(answer ->
                    answer.getReplies().stream().filter(reply ->
                            !reply.getValue().equals("INCORRECT")).collect(Collectors.toList())));
  

Большое спасибо

Комментарии:

1. Ну, вы создаете новый список, но ничего с ним не делаете.

2. » не работает » совсем не помогает. Вы проверили, что ваш код на самом деле делает с отладчиком?

3. Какой объект вы пытаетесь удалить? User , или Question или Reply ?

4. Спасибо за ваши ответы: я пытаюсь вернуть целые объекты пользователей.. с отфильтрованными неправильными ответами

5. Обратите внимание, что вы должны следовать соглашениям об именовании Java: имена переменных начинаются со строчной буквы (т.е. Users должны быть users ).

Ответ №1:

Если вы хотите собирать только ответы, попробуйте это:

 List<Reply> correctReplies = Users.stream()
    .flatMap(user -> user.getAnswers().stream())
    .flatMap(answer -> answer.getReplies().stream())
    .filter(reply -> !reply.getValue().equals("INCORRECT"))
    .collect(Collectors.toList());
  

Чтобы получить только пользователя с любым правильным ответом:

 List<User> usersWithCorrectReplies = Users.stream()
    .filter(user -> user.getAnswers().stream()
            .flatMap(answer -> answer.getReplies().stream())
            .anyMatch(reply -> !reply.getValue().equals("INCORRECT"))
    )
    .collect(Collectors.toList());
  

Если вы хотите фильтровать только правильные ответы от пользователя, вам нужно изменить свой класс, потому что за это отвечает этот объект:

 class User {
    List<Answer> getAnswers() { ... }

    List<Reply> correctReplies() {
        return getAnswers().stream()
                .flatMap(answer -> answer.getReplies().stream())
                .filter(reply -> !reply.getValue().equals("INCORRECT"))
                .collect(Collectors.toList());
    }

    boolean hasCorrectReplies() {
        return getAnswers().stream()
                .flatMap(answer -> answer.getReplies().stream())
                .anyMatch(reply -> !reply.getValue().equals("INCORRECT"));
    }
}
  

Затем вы можете использовать его:

 List<User> usersWithCorrectReplies2 = Users.stream()
    .filter(User::hasCorrectReplies)
    .collect(Collectors.toList());

usersWithCorrectReplies2.forEach(user -> user.correctReplies()
    .forEach(System.out::println));
  

Комментарии:

1. Спасибо за ваш ответ.. Я хотел вернуть все объекты пользователей с отфильтрованными неправильными ответами

2. Я не думаю, что это возможно, для этого нужно было бы изменить реализацию getReplies метода. Или вы имеете в виду, что вам нужны только пользователи, у которых есть несколько правильных ответов?

3. Нет, я действительно хочу отфильтровать неправильные ответы. Я думал о том, чтобы, возможно, сделать это через геттеры… Я не знаю, является ли это хорошей практикой..