FlatMappingTraverser implements Traverser<R> { @Override public R next() { do { R r = currentTraverser.next(); if (r != null) { return r; } currentTraverser = nextTraverser(); } while (currentTraverser != NULL_TRAVERSER); return null; } FlatMappingTraverser(Traverser<T> wrapped, Function<? super T, ? extends Traverser<? extends R>> mapper); @Override R next();  }
@Test public void smokeTest() { FlatMappingTraverser<Integer, Integer> trav = new FlatMappingTraverser<>( traverseItems(0, 1, 2, 3), numItems -> traverseStream(IntStream.range(0, numItems).boxed())); assertEquals(0, (int) trav.next()); assertEquals(0, (int) trav.next()); assertEquals(1, (int) trav.next()); assertEquals(0, (int) trav.next()); assertEquals(1, (int) trav.next()); assertEquals(2, (int) trav.next()); assertNull(trav.next()); assertNull(trav.next()); }
@Test public void when_flatMapToNullTraverser_then_skipOverToNext() { FlatMappingTraverser<Integer, String> trav = new FlatMappingTraverser<>(traverseItems(1, 2, 3), item -> item != 3 ? empty() : singleton("a")); assertEquals("a", trav.next()); assertNull(trav.next()); assertNull(trav.next()); }