src/main/java/io/reactivex/Flowable.java
@CheckReturnValue
    @NonNull
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerSupport.NONE)
    public static <T, R> Flowable<R> zip(Iterable<? extends Publisher<? extends T>> sources, Function<? super Object[], ? extends R> zipper) {
        ObjectHelper.requireNonNull(zipper, "zipper is null");
        ObjectHelper.requireNonNull(sources, "sources is null");
        return RxJavaPlugins.onAssembly(new FlowableZip<T, R>(null, sources, zipper, bufferSize(), false));
    }
@CheckReturnValue
    @NonNull
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerSupport.NONE)
    public static <T, R> Flowable<R> zip(Iterable<? extends Publisher<? extends T>> sources, Function<? super Object[], ? extends R> zipper) {
        ObjectHelper.requireNonNull(zipper, "zipper is null");
        ObjectHelper.requireNonNull(sources, "sources is null");
        return RxJavaPlugins.onAssembly(new FlowableZip<T, R>(null, sources, zipper, bufferSize(), false));
    }
Returns a Flowable that emits the results of a specified combiner function applied to combinations of
items emitted, in sequence, by an Iterable of other Publishers.
<p>
{@code zip} applies this function in strict sequence, so the first item emitted by the new Publisher
will be the result of the function applied to the first item emitted by each of the source Publishers;
the second item emitted by the new Publisher will be the result of the function applied to the second
item emitted by each of those Publishers; and so forth.
<p>
The resulting {@code Publisher<R>} returned from {@code zip} will invoke {@code onNext} as many times as
the number of {@code onNext} invocations of the source Publisher that emits the fewest items.
<p>
The operator subscribes to its sources in the order they are specified and completes eagerly if
one of the sources is shorter than the rest while canceling the other sources. Therefore, it
is possible those other sources will never be able to run to completion (and thus not calling
{@code doOnComplete()}). This can also happen if the sources are exactly the same length; if
source A completes and B has been consumed and is about to complete, the operator detects A won't
be sending further values and it will cancel B immediately. For example:
<pre><code>zip(Arrays.asList(range(1, 5).doOnComplete(action1), range(6, 5).doOnComplete(action2)), (a) -&gt; a)</code></pre>
{@code action1} will be called but {@code action2} won't.
<br>To work around this termination property,
use {@link #doOnCancel(Action)} as well or use {@code using()} to do cleanup in case of completion
or cancellation.
<p>
<img width="640" height="380" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/zip.png" alt="">
<dl>
<dt><b>Backpressure:</b></dt>
<dd>The operator expects backpressure from the sources and honors backpressure from the downstream.
(I.e., zipping with {@link #interval(long, TimeUnit)} may result in MissingBackpressureException, use
one of the {@code onBackpressureX} to handle similar, backpressure-ignoring sources.</dd>
<dt><b>Scheduler:</b></dt>
<dd>{@code zip} does not operate by default on a particular {@link Scheduler}.</dd>
</dl>

@param <T> the common value type
@param <R> the zipped result type
@param sources
an Iterable of source Publishers
@param zipper
a function that, when applied to an item emitted by each of the source Publishers, results in
an item that will be emitted by the resulting Publisher
@return a Flowable that emits the zipped results
@see <a href="http://reactivex.io/documentation/operators/zip.html">ReactiveX operators documentation: Zip</a>