Итерация и фильтрация списка с использованием Java streams вместо цикла for-each

#java #lambda

#java #лямбда — выражение

Вопрос:

В своего рода чате с чат-ботом, который я внедряю, у меня есть список разговоров, и у каждого разговора есть список сообщений. Я хочу добавить те разговоры, последнее сообщение которых не является сообщением чат-бота и не просматривается пользователем, в список разговоров. Чтобы сделать это, я кодирую его следующим образом:

 List<ConversationDto> conversationsToBeSent = new ArrayList<>();

for (ConversationDto conversation : super.allConversations) {
    if (conversation.getMessages() != null) {
        if (conversation.getMessages().get(0).getMessageType().getId() != MessageTypeEnum.CHATBOT.getValue()
                amp;amp; conversation.getMessages().get(0).getToViewedAt() == null) {
            conversationsToBeSent.add(conversation);
        }
    }

}
 

Это работает.
Вопрос в том, как я могу закодировать это, используя Lambda и stream вместо for each .

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

1. Привет! Пожалуйста, покажите нам, что вы пробовали до сих пор, чтобы мы могли видеть, с чем вам нужна помощь

Ответ №1:

Ваша проблема — классическая задача «Фильтровать коллекцию». Это то, что Stream.filter() делает метод.

Блок кода:

 List<Item> newList = new ArrayList<>();
for (Item item : collection) {
    if (predicate(item)) {
        newList.add(item);
    }
}
 

обычно может быть преобразован в:

 List<Item> newList = 
    collection
        .stream()
        .filter(item -> predicate(item))
        .collect(Collectors.toList());
 

В вашем случае код преобразуется следующим образом.
Обратите внимание на комментарии в следующем блоке кода для объяснений:

 List<ConversationDto> conversationsToBeSent = super.allConversations // Start with the original list
    .stream() // Get a stream of list items
    .filter(conversation -> // Filter the list items
        conversation.getMessages() != null
        amp;amp; !conversation.getMessages().isEmpty() // YOU PROBABLY WANT THIS CHECK AS WELL!
        amp;amp; conversation.getMessages().get(0).getMessageType().getId() != MessageTypeEnum.CHATBOT.getValue()
        amp;amp; conversation.getMessages().get(0).getToViewedAt() == null
    )
    .collect(Collectors.toList()); // Collect the stream items to a new list
 

Ответ №2:

Чтобы использовать stream в списке, просто сделайте super.allConversations.stream() это, если вы хотите выбрать только некоторые элементы, вы можете использовать filter метод, как в приведенном ниже коде:

 super.allConversations.stream().filter(
  conversation ->
    conversion != null amp;amp; 
    conversation.getMessages().get(0).getMessageType().getId() != MessageTypeEnum.CHATBOT.getValue() amp;amp;
    conversation.getMessages().get(0).getToViewedAt() == null
);