src/main/java/io/reactivex/Observable.java
@CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public final <TRight, TLeftEnd, TRightEnd, R> Observable<R> join(
            ObservableSource<? extends TRight> other,
            Function<? super T, ? extends ObservableSource<TLeftEnd>> leftEnd,
            Function<? super TRight, ? extends ObservableSource<TRightEnd>> rightEnd,
            BiFunction<? super T, ? super TRight, ? extends R> resultSelector
                    ) {
        ObjectHelper.requireNonNull(other, "other is null");
        ObjectHelper.requireNonNull(leftEnd, "leftEnd is null");
        ObjectHelper.requireNonNull(rightEnd, "rightEnd is null");
        ObjectHelper.requireNonNull(resultSelector, "resultSelector is null");
        return RxJavaPlugins.onAssembly(new ObservableJoin<T, TRight, TLeftEnd, TRightEnd, R>(
                this, other, leftEnd, rightEnd, resultSelector));
    }
@CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public final <TRight, TLeftEnd, TRightEnd, R> Observable<R> join(
            ObservableSource<? extends TRight> other,
            Function<? super T, ? extends ObservableSource<TLeftEnd>> leftEnd,
            Function<? super TRight, ? extends ObservableSource<TRightEnd>> rightEnd,
            BiFunction<? super T, ? super TRight, ? extends R> resultSelector
                    ) {
        ObjectHelper.requireNonNull(other, "other is null");
        ObjectHelper.requireNonNull(leftEnd, "leftEnd is null");
        ObjectHelper.requireNonNull(rightEnd, "rightEnd is null");
        ObjectHelper.requireNonNull(resultSelector, "resultSelector is null");
        return RxJavaPlugins.onAssembly(new ObservableJoin<T, TRight, TLeftEnd, TRightEnd, R>(
                this, other, leftEnd, rightEnd, resultSelector));
    }
Correlates the items emitted by two ObservableSources based on overlapping durations.
<p>
There are no guarantees in what order the items get combined when multiple
items from one or both source ObservableSources overlap.
<p>
<img width="640" height="380" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/join_.png" alt="">
<dl>
<dt><b>Scheduler:</b></dt>
<dd>{@code join} does not operate by default on a particular {@link Scheduler}.</dd>
</dl>

@param <TRight> the value type of the right ObservableSource source
@param <TLeftEnd> the element type of the left duration ObservableSources
@param <TRightEnd> the element type of the right duration ObservableSources
@param <R> the result type
@param other
the second ObservableSource to join items from
@param leftEnd
a function to select a duration for each item emitted by the source ObservableSource, used to
determine overlap
@param rightEnd
a function to select a duration for each item emitted by the {@code right} ObservableSource, used to
determine overlap
@param resultSelector
a function that computes an item to be emitted by the resulting ObservableSource for any two
overlapping items emitted by the two ObservableSources
@return an Observable that emits items correlating to items emitted by the source ObservableSources that have
overlapping durations
@see <a href="http://reactivex.io/documentation/operators/join.html">ReactiveX operators documentation: Join</a>