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}