Combining streams in Java

July 31, 2013

Given an interface Stream:

interface Stream<A> {
  A head();
  Stream<A> tail();
}

And using a test function startsWith:

class StreamTest {

  private static void assertEquals(Object x, Object y) {
    if (!x.equals(y)) {
      throw new AssertionError(x.toString() + " != " + y.toString());
    }
  }

  static <A> void startsWith(Stream<A> s, A a, A b, A c) {
    assertEquals(s.tail().tail().head(), c);
    assertEquals(s.tail().head(), b);
    assertEquals(s.head(), a);
  }

}

Let's write some stream implementations.

Constant value streams

Write the functions zeroes, ones, and twos, which return streams of values 0, 1, and 2, respectively:

Stream<Integer> zeroes() {
  return null;
}

Stream<Integer> ones() {
  return null;
}

Stream<Integer> twos() {
  return null;
}
startsWith(zeroes(), 0, 0, 0);
startsWith(ones(), 1, 1, 1);
startsWith(twos(), 2, 2, 2);

Natural numbers streams

Write the functions evenNats and oddNats, which return streams of the even natural numbers (0, 2, 4, ...) and the odd natural numbers (1, 3, 5, ...), respectively:

Stream<Integer> evenNats() {
  return null;
}

Stream<Integer> oddNats() {
  return null;
}
startsWith(evenNats(), 0, 2, 4);
startsWith(oddNats(), 1, 3, 5);

Combined streams

Write the function combine, which interleaves its argument streams in constant time:

static <A> Stream<A> combine(Stream<A>... ss) {
  return null;
}
startsWith(combine(evenNats(), oddNats()), 0, 1, 2);