Search code examples
javalambdajava-8java-streamcollectors

Java 8 conditional logic inside Peek?


I currently have some Java 8 code which looks like this - pretty sure I could combine this into a single call, but not sure how to get my conditional call in place inside the Looped map. Is it possible to do this with peek()? Or other Java 8 call?

Current code

//turn above groups into a map, grouped by Resolution
Map<Long,List<LeadChannel>> mappedUp = groups
                .stream()
                .collect( Collectors.groupingBy( channel->channel.getResolution().getId() ) );

Next bit converts to a Map of String manually based on the ID of the Key.

Map<String, List<LeadChannel>> finalMap = new HashMap<String, List<LeadChannel>>();

for ( Map.Entry<Long,List<LeadChannel>> entry : mappedUp.entrySet()) {
    if(  !entry.getKey().equals( RESOLVED_STATUS ) ) {
        finalMap.put( "unresolved", entry.getValue() );
    } else {
        finalMap.put( "resolved", entry.getValue() );
    }
}

I am trying to do it something like:

 Map<String,List<LeadChannel>> mappedUp = groups
                        .stream()
                        .collect( Collectors.groupingBy( channel->channel.getResolution().getId() ) )
.entrySet()
.stream()
.peek( if statement etc.. )

Solution

  • What you seem to be looking for is a conditional groupingBy as:

    Map<String, List<LeadChannel>> finalMap = groups
            .stream()
            .collect(Collectors.groupingBy(channel ->
                    channel.getResolution().getId().equals(RESOLVED_STATUS) ?
                            "unresolved" : "resolved"));
    

    Or in multiple pipelines, to understand how you can partition the data and then map it further based on the condition shared in the question:

    Map<Boolean, List<LeadChannel>> mappedUp = groups
            .stream()
            .collect(Collectors.partitioningBy(channel -> 
                    channel.getResolution().getId().equals(RESOLVED_STATUS)));
    
    Map<String, List<LeadChannel>> finalMap = mappedUp.entrySet().stream()
            // in a similar manner you can map your current map's entries as well
            .map(e -> new AbstractMap.SimpleEntry<>(e.getKey() ? "resolved" : "unresolved", e.getValue())) 
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    

    or as Holger suggested, better with the use of lambda directly collect as

    Map<String, List<LeadChannel>> finalMap = mappedUp.entrySet().stream()
            .collect(Collectors.toMap(e -> e.getKey()? "resolved": "unresolved", Map.Entry::getValue))