javalambdajava-8java-stream

How can I convert a Stream of Strings to Stream of String pairs?


I want to take a stream of strings and turn it into a stream of word pairs. eg:

I have: { "A", "Apple", "B", "Banana", "C", "Carrot" }

I want: { ("A", "Apple"), ("Apple", "B"), ("B", "Banana"), ("Banana", "C") }.

This is nearly the same as Zipping, as outlined at Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip)

However, that produces: { (A, Apple), (B, Banana), (C, Carrot) }

The following code works, but is clearly the wrong way to do it (not thread safe etc etc):

static String buffered = null;

static void output(String s) {
    String result = null;
    if (buffered != null) {
        result = buffered + "," + s;
    } else {
        result = null;
    }

    buffered = s;
    System.out.println(result);
}

// ***** 

Stream<String> testing = Stream.of("A", "Apple", "B", "Banana", "C", "Carrot");
testing.forEach(s -> {output(s);});

Solution

  • Java 24 has built-in support for sliding windows using the Gatherers.windowSliding method. This does exactly what you want.

    Stream<String> testing = Stream.of("A", "Apple", "B", "Banana", "C", "Carrot");
    
    // [A, Apple], [Apple, B], [B, Banana], [Banana, C], [C, Carrot]]
    Stream<List<String>> wordPairs = testing.gather(Gatherers.windowSliding(2));