/** * Returns a composed function that first applies this function to * its input, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <V> the type of output of the {@code after} function, and of the * composed function * @param after the function to apply after this function is applied * @return a composed function that first applies this function and then * applies the {@code after} function * @throws NullPointerException if after is null * * @see #compose(IndexedFunction) */ default <V> IndexedFunction<T, V> andThen( IndexedFunction<? super R, ? extends V> after) { Objects.requireNonNull(after); return (int index, T t) -> after.apply(index, apply(index, t)); }
/** * Returns a composed function that first applies the {@code before} * function to its input, and then applies this function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <V> the type of input to the {@code before} function, and to the * composed function * @param before the function to apply before this function is applied * @return a composed function that first applies the {@code before} * function and then applies this function * @throws NullPointerException if before is null * * @see #andThen(IndexedFunction) */ default <V> IndexedFunction<V, R> compose( IndexedFunction<? super V, ? extends T> before) { Objects.requireNonNull( before); return (int index, V v) -> apply(index, before.apply(index, v)); }
/** * Returns a composed function that first applies this function to * its input, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <V> the type of output of the {@code after} function, and of the * composed function * @param after the function to apply after this function is applied * @return a composed function that first applies this function and then * applies the {@code after} function * @throws NullPointerException if after is null * * @see #compose(IndexedFunction) */ default <V> IndexedFunction<T, V> andThen( IndexedFunction<? super R, ? extends V> after) { Objects.requireNonNull(after); return (int index, T t) -> after.apply(index, apply(index, t)); }
/** * Returns a composed function that first applies the {@code before} * function to its input, and then applies this function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <V> the type of input to the {@code before} function, and to the * composed function * @param before the function to apply before this function is applied * @return a composed function that first applies the {@code before} * function and then applies this function * @throws NullPointerException if before is null * * @see #andThen(IndexedFunction) */ default <V> IndexedFunction<V, R> compose( IndexedFunction<? super V, ? extends T> before) { Objects.requireNonNull( before); return (int index, V v) -> apply(index, before.apply(index, v)); }
/** * Applies the given {@code transform} function to each element and its index in the original collection * and appends the results to the given {@code destination}. * * @param transform function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. */ public static <T, R, C extends Collection<? super R>> C mapIndexedTo( @This Iterable<T> thiz, C destination, IndexedFunction<T, R> transform ) { int index = 0; for( T item : thiz ) { destination.add( transform.apply( index++, item ) ); } return destination; }
/** * Applies the given {@code transform} function to each element and its index in the original collection * and appends only the non-null results to the given {@code destination}. * * @param transform function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. */ public static <T, R, C extends Collection<? super R>> C mapIndexedNotNullTo( @This Iterable<T> thiz, C destination, IndexedFunction<T, R> transform ) { thiz.forEachIndexed( ( index, element ) -> { R result = transform.apply( index, element ); if( result != null ) { destination.add( result ); } } ); return destination; }