/** * A converting function from Object array to {@link Tuple3} to R. * * @param <T1> The type of the first value. * @param <T2> The type of the second value. * @param <T3> The type of the third value. * @param <R> The type of the return value. * @param delegate the function to delegate to * * @return The unchecked conversion function to R. */ public static <T1, T2, T3, R> Function<Object[], R> fn3(final Function<Tuple3<T1, T2, T3>, R> delegate) { return objects -> delegate.apply(Tuples.<T1, T2, T3>fn3().apply(objects)); }
/** * Zip three sources together, that is to say wait for all the sources to emit one * element and combine these elements once into a {@link Tuple3}. * The operator will continue doing so until any of the sources completes. * Errors will immediately be forwarded. * This "Step-Merge" processing is especially useful in Scatter-Gather scenarios. * <p> * <img class="marble" src="doc-files/marbles/zipFixedSourcesForFlux.svg" alt=""> * * @param source1 The first upstream {@link Publisher} to subscribe to. * @param source2 The second upstream {@link Publisher} to subscribe to. * @param source3 The third upstream {@link Publisher} to subscribe to. * @param <T1> type of the value from source1 * @param <T2> type of the value from source2 * @param <T3> type of the value from source3 * * @return a zipped {@link Flux} */ public static <T1, T2, T3> Flux<Tuple3<T1, T2, T3>> zip(Publisher<? extends T1> source1, Publisher<? extends T2> source2, Publisher<? extends T3> source3) { return zip(Tuples.fn3(), source1, source2, source3); }
@Test public void fn3() { Integer[] source = new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8 }; Tuple3<Object, Object, Object> tuple = Tuples.fn3().apply(source); assertThat(tuple.getT1()).isEqualTo(1); assertThat(tuple.getT2()).isEqualTo(2); assertThat(tuple.getT3()).isEqualTo(3); assertThat(tuple) .isInstanceOf(Tuple8.class) .containsExactly(1, 2, 3, 4, 5, 6, 7, 8); }
@Test public void fn3Delegate() { Integer[] source = new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8 }; Function<Tuple3<Integer, Integer, Integer>, Tuple3> invert = t3 -> new Tuple3<>(t3.getT3(), t3.getT2(), t3.getT1()); Tuple3 tuple = Tuples.fn3(invert).apply(source); assertThat(tuple.getT1()).isEqualTo(3); assertThat(tuple.getT2()).isEqualTo(2); assertThat(tuple.getT3()).isEqualTo(1); assertThat((Object) tuple).isExactlyInstanceOf(Tuple3.class); }
@Test public void whenIterableDoesntCombineErrors() { Exception boom1 = new NullPointerException("boom1"); Exception boom2 = new IllegalArgumentException("boom2"); StepVerifier.create(Mono.zip( Arrays.asList(Mono.just("foo"), Mono.<String>error(boom1), Mono.<String>error(boom2)), Tuples.fn3())) .verifyErrorMatches(e -> e == boom1); }
@Test public void whenIterableDelayErrorCombinesErrors() { Exception boom1 = new NullPointerException("boom1"); Exception boom2 = new IllegalArgumentException("boom2"); StepVerifier.create(Mono.zipDelayError( Arrays.asList(Mono.just("foo"), Mono.<String>error(boom1), Mono.<String>error(boom2)), Tuples.fn3())) .verifyErrorMatches(e -> e.getMessage().equals("Multiple exceptions") && e.getSuppressed()[0] == boom1 && e.getSuppressed()[1] == boom2); }
/** * A converting function from Object array to {@link Tuple3} to R. * * @param <T1> The type of the first value. * @param <T2> The type of the second value. * @param <T3> The type of the third value. * @param <R> The type of the return value. * @param delegate the function to delegate to * * @return The unchecked conversion function to R. */ public static <T1, T2, T3, R> Function<Object[], R> fn3(final Function<Tuple3<T1, T2, T3>, R> delegate) { return objects -> delegate.apply(Tuples.<T1, T2, T3>fn3().apply(objects)); }
/** * Zip three sources together, that is to say wait for all the sources to emit one * element and combine these elements once into a {@link Tuple3}. * The operator will continue doing so until any of the sources completes. * Errors will immediately be forwarded. * This "Step-Merge" processing is especially useful in Scatter-Gather scenarios. * <p> * <img class="marble" src="doc-files/marbles/zipFixedSourcesForFlux.svg" alt=""> * * @param source1 The first upstream {@link Publisher} to subscribe to. * @param source2 The second upstream {@link Publisher} to subscribe to. * @param source3 The third upstream {@link Publisher} to subscribe to. * @param <T1> type of the value from source1 * @param <T2> type of the value from source2 * @param <T3> type of the value from source3 * * @return a zipped {@link Flux} */ public static <T1, T2, T3> Flux<Tuple3<T1, T2, T3>> zip(Publisher<? extends T1> source1, Publisher<? extends T2> source2, Publisher<? extends T3> source3) { return zip(Tuples.fn3(), source1, source2, source3); }