使用Java流而不是for-each循环迭代和过滤列表
在与我正在实施的聊天机器人的一种聊天中,我有一个对话列表,每个对话都有一个消息列表。我想将其最后一条消息不是聊天机器人消息且用户未查看的那些对话添加到对话列表中。为此,我将其编码如下:
List<ConversationDto> conversationsToBeSent = new ArrayList<>();
for (ConversationDto conversation : super.allConversations) {
if (conversation.getMessages() != null) {
if (conversation.getMessages().get(0).getMessageType().getId() != MessageTypeEnum.CHATBOT.getValue()
&& conversation.getMessages().get(0).getToViewedAt() == null) {
conversationsToBeSent.add(conversation);
}
}
}
这是有效的。问题是我如何使用 Lambda 和流而不是每个进行编码。
回答
您的问题是经典的“过滤集合”任务。这就是该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
&& !conversation.getMessages().isEmpty() // YOU PROBABLY WANT THIS CHECK AS WELL!
&& conversation.getMessages().get(0).getMessageType().getId() != MessageTypeEnum.CHATBOT.getValue()
&& conversation.getMessages().get(0).getToViewedAt() == null
)
.collect(Collectors.toList()); // Collect the stream items to a new list