Java中流过滤器的更好方法

men*_*eng 5 java for-loop java-stream

有没有办法使用流简化过滤器?或者让它更短或优化?我不太确定在这种情况下使用 for 循环是否更好。

我只是想使用 failedIds 将失败消息和成功消息分开。

这是我的代码

List<Message> successMessages = messageList.stream()
        .filter(message -> !failedMessageIds.contains(message.getId()))
        .collect(Collectors.toList());

List<Message> failedMessages = messageList.stream()
        .filter(message -> failedMessageIds.contains(message.getId()))
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

谢谢!

Rav*_*ala 7

您可以groupingBy在这里使用收集器。此解决方案仅通过集合一次。还要确保使用Setfor failedMessageIds

Map<Boolean, List<Message>> messagesByStateMap = messageList.stream()
    .collect(Collectors.groupingBy(m -> !failedMessageIds.contains(m.getId())));
List<Message> successMessages = messagesByStateMap.get(true);
Run Code Online (Sandbox Code Playgroud)

更好的方法是使用partitioningBy以下评论中所述的收集器,因为您的分类器函数只是一个Predicate.

Map<Boolean, List<Message>> messagesByStateMap = messageList.stream()
    .collect(Collectors.partitioningBy(m -> !failedMessageIds.contains(m.getId())));
Run Code Online (Sandbox Code Playgroud)

然而,由于流的使用引发了一些争议,这里是使用 Java 8 的等效迭代解决方案。

for (Message message : messageList)
    messagesByStateMap.computeIfAbsent(!failedMessageIds.contains(message.getId()), 
        unused -> new ArrayList<>())
    .add(message);
Run Code Online (Sandbox Code Playgroud)

  • 这可能只是一个品味问题,但如果我期望结果图中有两个以上的组,我会使用“groupingBy”。如果正好有两个组,我更喜欢“partitioningBy”,例如:“messageList.stream().collect(Collectors.partitioningBy(failedMessageIds::contains));” (3认同)