    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.lang3.function;
    019
    020import java.util.Objects;
    021import java.util.Optional;
    022import java.util.function.Function;
    023
    024/**
    025 * Factory for {@link Function}.
    026 *
    027 * @since 3.14.0
    028 */
    029public final class Functions {
    030
    031    /**
    032     * Applies the {@link Function} on the object if the function is not {@code null}. Otherwise, does nothing and returns {@code null}.
    033     *
    034     * @param function the function to apply.
    035     * @param object   the object to apply the function.
    036     * @param <T>      the type of the argument the function applies.
    037     * @param <R>      the type of the result the function returns.
    038     * @return the value the function returns if the function is not {@code null}; {@code null} otherwise.
    039     * @since 3.15.0
    040     */
    041    public static <T, R> R apply(final Function<T, R> function, final T object) {
    042        return function != null ? function.apply(object) : null;
    043    }
    044
    045    /**
    046     * Applies a value to a function if the value isn't {@code null}, otherwise the method returns {@code null}. If the value isn't {@code null} then return the
    047     * result of the applying function.
    048     *
    049     * <pre>{@code
    050     * Functions.applyNonNull("a", String::toUpperCase)  = "A"
    051     * Functions.applyNonNull(null, String::toUpperCase) = null
    052     * Functions.applyNonNull("a", s -> null)            = null
    053     * }</pre>
    054     * <p>
    055     * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
    056     * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
    057     * </p>
    058     *
    059     * @param <T>    The type of the input of this method and the function.
    060     * @param <R>    The type of the result of the function and this method.
    061     * @param value  The value to apply the function to, may be {@code null}.
    062     * @param mapper The function to apply, must not be {@code null}.
    063     * @return The result of the function (which may be {@code null}) or {@code null} if the input value is {@code null}.
    064     * @see #applyNonNull(Object, Function, Function)
    065     * @see #applyNonNull(Object, Function, Function, Function)
    066     * @since 3.19.0
    067     */
    068    public static <T, R> R applyNonNull(final T value, final Function<? super T, ? extends R> mapper) {
    069        return value != null ? Objects.requireNonNull(mapper, "mapper").apply(value) : null;
    070    }
    071
    072    /**
    073     * Applies values to a chain of functions, where a {@code null} can short-circuit each step. A function is only applied if the previous value is not
    074     * {@code null}, otherwise this method returns {@code null}.
    075     *
    076     * <pre>{@code
    077     * Functions.applyNonNull(" a ", String::toUpperCase, String::trim) = "A"
    078     * Functions.applyNonNull(null, String::toUpperCase, String::trim)  = null
    079     * Functions.applyNonNull(" a ", s -> null, String::trim)           = null
    080     * Functions.applyNonNull(" a ", String::toUpperCase, s -> null)    = null
    081     * }</pre>
    082     * <p>
    083     * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
    084     * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
    085     * </p>
    086     *
    087     * @param <T>     The type of the input of this method and the first function.
    088     * @param <U>     The type of the result of the first function and the input to the second function.
    089     * @param <R>     The type of the result of the second function and this method.
    090     * @param value1  The value to apply the functions to, may be {@code null}.
    091     * @param mapper1 The first function to apply, must not be {@code null}.
    092     * @param mapper2 The second function to apply, must not be {@code null}.
    093     * @return The result of the final function (which may be {@code null}) or {@code null} if the input value or any intermediate value is {@code null}.
    094     * @see #applyNonNull(Object, Function)
    095     * @see #applyNonNull(Object, Function, Function, Function)
    096     * @since 3.19.0
    097     */
    098    public static <T, U, R> R applyNonNull(final T value1, final Function<? super T, ? extends U> mapper1, final Function<? super U, ? extends R> mapper2) {
    099        return applyNonNull(applyNonNull(value1, mapper1), mapper2);
    100    }
    101
    102    /**
    103     * Applies values to a chain of functions, where a {@code null} can short-circuit each step. A function is only applied if the previous value is not
    104     * {@code null}, otherwise this method returns {@code null}.
    105     *
    106     * <pre>{@code
    107     * Functions.applyNonNull(" abc ", String::toUpperCase, String::trim, StringUtils::reverse) = "CBA"
    108     * Functions.applyNonNull(null, String::toUpperCase, String::trim, StringUtils::reverse)    = null
    109     * Functions.applyNonNull(" abc ", s -> null, String::trim, StringUtils::reverse)           = null
    110     * Functions.applyNonNull(" abc ", String::toUpperCase, s -> null, StringUtils::reverse)    = null
    111     * Functions.applyNonNull(" abc ", String::toUpperCase, String::trim, s -> null)            = null
    112     * }</pre>
    113     * <p>
    114     * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
    115     * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
    116     * </p>
    117     *
    118     * @param <T>     The type of the input of this method and the first function.
    119     * @param <U>     The type of the result of the first function and the input to the second function.
    120     * @param <V>     The type of the result of the second function and the input to the third function.
    121     * @param <R>     The type of the result of the third function and this method.
    122     * @param value1  The value to apply the first function, may be {@code null}.
    123     * @param mapper1 The first function to apply, must not be {@code null}.
    124     * @param mapper2 The second function to apply, must not be {@code null}.
    125     * @param mapper3 The third function to apply, must not be {@code null}.
    126     * @return The result of the final function (which may be {@code null}) or {@code null} if the input value or any intermediate value is {@code null}.
    127     * @see #applyNonNull(Object, Function)
    128     * @see #applyNonNull(Object, Function, Function)
    129     * @since 3.19.0
    130     */
    131    public static <T, U, V, R> R applyNonNull(final T value1, final Function<? super T, ? extends U> mapper1, final Function<? super U, ? extends V> mapper2,
    132            final Function<? super V, ? extends R> mapper3) {
    133        return applyNonNull(applyNonNull(applyNonNull(value1, mapper1), mapper2), mapper3);
    134    }
    135
    136    /**
    137     * Starts a fluent chain like {@code function(foo::bar).andThen(...).andThen(...).apply(...);}
    138     *
    139     * @param <T>      Input type.
    140     * @param <R>      Return type.
    141     * @param function the argument to return.
    142     * @return the argument
    143     */
    144    public static <T, R> Function<T, R> function(final Function<T, R> function) {
    145        return function;
    146    }
    147
    148    private Functions() {
    149        // no instances needed.
    150    }
    151}