Better approach for stream filter in Java

mengmeng :

Is there a way to simplify filter using stream? Or for it to be shorter or optimized? I'm not quite sure if using a for loop would be better to use in this scenario.

I'm just trying to separate the failed and the success messages using the failedIds.

Here is my code

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());

Thank you!

Ravindra Ranwala :

You may use groupingBy collector here. This solution passes over the collection only once. Also make sure to use a Set for failedMessageIds.

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

A much better approach would be to use the partitioningBy collector as stated in the following comment since your classifier function is a just a Predicate.

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

However, since the use of streams has sparked some controversy, here's the equivalent iterative solution using Java 8.

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=316885&siteId=1