Search code examples
javalambdajava-8java-stream

Java 8 lambda: iterate over stream objects and use previous/next object(s) in stream


I am practising some entry-level java 8 lambda functionality.

Given a list of messages, each containing a message offset, where all offsets must form a consecutive list of integers, I'm trying to find gaps to warn about. I get the feeling this all should be well doable with a nice lambda. But I can't get my head around it.

So, there's this working snippet:

private void warnAboutMessageGaps(final List<Message> messages) {

    final List<Long> offsets = messages.stream()
            .sorted(comparingLong(Message::getOffset))
            .map(Message::getOffset)
            .collect(toList())
            ;

    for (int i = 0; i < offsets.size() - 1; i++) {
        final long currentOffset = offsets.get(i);
        final long expectedNextOffset = offsets.get(i) + 1;
        final long actualNextOffset = offsets.get(i + 1);
        if (currentOffset != expectedNextOffset) {
            LOG.error("Missing offset(s) found in messages: missing from {} to {}", currentOffset + 1, actualNextOffset - 1);
        }
    }
}

What I can't figure out is how to make it so that I can do the "compare with previous/next object" in the lambda. Any pointers would be appreciated.

/edit: Suggestions about StreamEx and other third-party solutions, while appreciated, are not what I was looking for.


Solution

  • for the present problem, this approach seems to be more suitable

    messages.stream().sorted( Comparator.comparingLong( Message::getOffset ) )
      .reduce( (m1, m2) -> {
        if( m1.getOffset() + 1 != m2.getOffset() )
          LOG.error( "Missing offset(s) found in messages: missing from {} to {}", m1.getOffset(), m2.getOffset() );
        return( m2 );
      } );
    

    This solution uses reduce away from its intended use. It solely uses the ability of reduce to go over all the pairs in a stream.
    The result of reduce is not used. (It would be impossible to use the result any further, because that would require a mutable reduction.)