Stream implements Iterable<T> { public <R> Stream<R> flatMap(final Func1<? super T, ? extends Iterable<? extends R>> func) { return new Stream<R>() { @Override public Iterator<R> iterator() { return new ReadOnlyIterator<R>() { Iterator<T> iterator = Stream.this.iterator(); Iterator<? extends R> next; @Override public boolean hasNext() { while ((next == null || !next.hasNext()) && iterator.hasNext()) { next = func.call(iterator.next()).iterator(); } return next != null && next.hasNext(); } @Override public R next() { return next.next(); } }; } }; }  static Stream<T> stream(final T[] array); static Stream<T> stream(final Iterable<T> source); static Stream<T> of(final T value); static Stream<T> of(T... values); static Stream<T> of(); R collect(Func1<Iterable<T>, R> collector); R reduce(R initial, Func2<R, T, R> accumulator); Optional<T> reduce(Func2<T, T, T> accumulator); Optional<T> first(); Optional<T> last(); Stream<R> compose(Func1<Stream<T>, Stream<R>> factory); Stream<R> map(final Func1<? super T, ? extends R> func); Stream<R> flatMap(final Func1<? super T, ? extends Iterable<? extends R>> func); Stream<T> filter(final Func1<? super T, Boolean> func); Stream<T> merge(final T value); Stream<T> separate(final T value); Stream<T> merge(final Iterable<? extends T> with); Stream<R> zipWith(final Iterable<? extends S> with, final Func2<? super T, ? super S, ? extends R> func); Stream<T> separate(Iterable<T> from); Stream<T> take(final int count); Stream<T> skip(final int count); Stream<T> distinct(); Stream<T> sort(final Comparator<T> comparator); Stream<T> reverse(); Stream<R> cast(final Class<R> c); boolean every(Func1<? super T, Boolean> predicate); boolean any(Func1<? super T, Boolean> predicate); Stream<Grouped<K, V>> groupBy(final Func1<? super T, ? extends K> groupSelector, final Func1<? super T, ? extends V> valueSelector); Stream<Grouped<K, T>> groupBy(final Func1<? super T, ? extends K> groupSelector); Stream<Indexed<T>> index(); void forEach(Action1<? super T> action); Stream<T> onNext(final Action1<? super T> action);  }
@Test public void testFlatMap() throws Exception { assertIterableEquals(asList("2", "3", "4", "3", "4", "5", "4", "5", "6"), of(1, 2, 3).flatMap(new Func1<Integer, Iterable<String>>() { @Override public Iterable<String> call(Integer value) {return asList("" + (value + 1), "" + (value + 2), "" + (value + 3));} })); assertIterableEquals(Arrays.asList(null, null, null, null), of(null, null).flatMap(new Func1<Object, Iterable<Object>>() { @Override public Iterable<Object> call(Object value) {return Arrays.asList(null, null);} })); assertIterableEquals(emptyList(), of().flatMap(new Func1<Object, Iterable<Object>>() { @Override public Iterable<Object> call(Object value) {return null;} })); HashMap<Integer, List<String>> map = new HashMap<Integer, List<String>>() {{ put(0, asList("1", "2")); put(1, Collections.<String>emptyList()); put(2, Collections.<String>emptyList()); put(3, Collections.<String>emptyList()); put(4, asList("3")); }}; assertIterableEquals(asList("1", "2", "3"), stream(map.entrySet()).flatMap(new Func1<Map.Entry<Integer, List<String>>, Iterable<String>>() { @Override public Iterable<String> call(Map.Entry<Integer, List<String>> value) { return value.getValue(); } })); HashMap<Integer, List<String>> map2 = new HashMap<Integer, List<String>>() {{ put(1, Collections.<String>emptyList()); put(2, Collections.<String>emptyList()); put(3, Collections.<String>emptyList()); put(0, asList("1", "2")); put(4, asList("3")); }}; assertIterableEquals(asList("1", "2", "3"), stream(map2.entrySet()).flatMap(new Func1<Map.Entry<Integer, List<String>>, Iterable<String>>() { @Override public Iterable<String> call(Map.Entry<Integer, List<String>> value) { return value.getValue(); } })); }