View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.lang3.function;
19  
20  import java.util.Objects;
21  import java.util.Optional;
22  import java.util.function.Function;
23  
24  /**
25   * Factory for {@link Function}.
26   *
27   * @since 3.14.0
28   */
29  public final class Functions {
30  
31      /**
32       * Applies the {@link Function} on the object if the function is not {@code null}. Otherwise, does nothing and returns {@code null}.
33       *
34       * @param function the function to apply.
35       * @param object   the object to apply the function.
36       * @param <T>      the type of the argument the function applies.
37       * @param <R>      the type of the result the function returns.
38       * @return the value the function returns if the function is not {@code null}; {@code null} otherwise.
39       * @since 3.15.0
40       */
41      public static <T, R> R apply(final Function<T, R> function, final T object) {
42          return function != null ? function.apply(object) : null;
43      }
44  
45      /**
46       * 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
47       * result of the applying function.
48       *
49       * <pre>{@code
50       * Functions.applyNonNull("a", String::toUpperCase)  = "A"
51       * Functions.applyNonNull(null, String::toUpperCase) = null
52       * Functions.applyNonNull("a", s -> null)            = null
53       * }</pre>
54       * <p>
55       * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
56       * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
57       * </p>
58       *
59       * @param <T>    The type of the input of this method and the function.
60       * @param <R>    The type of the result of the function and this method.
61       * @param value  The value to apply the function to, may be {@code null}.
62       * @param mapper The function to apply, must not be {@code null}.
63       * @return The result of the function (which may be {@code null}) or {@code null} if the input value is {@code null}.
64       * @see #applyNonNull(Object, Function, Function)
65       * @see #applyNonNull(Object, Function, Function, Function)
66       * @since 3.19.0
67       */
68      public static <T, R> R applyNonNull(final T value, final Function<? super T, ? extends R> mapper) {
69          return value != null ? Objects.requireNonNull(mapper, "mapper").apply(value) : null;
70      }
71  
72      /**
73       * 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
74       * {@code null}, otherwise this method returns {@code null}.
75       *
76       * <pre>{@code
77       * Functions.applyNonNull(" a ", String::toUpperCase, String::trim) = "A"
78       * Functions.applyNonNull(null, String::toUpperCase, String::trim)  = null
79       * Functions.applyNonNull(" a ", s -> null, String::trim)           = null
80       * Functions.applyNonNull(" a ", String::toUpperCase, s -> null)    = null
81       * }</pre>
82       * <p>
83       * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
84       * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
85       * </p>
86       *
87       * @param <T>     The type of the input of this method and the first function.
88       * @param <U>     The type of the result of the first function and the input to the second function.
89       * @param <R>     The type of the result of the second function and this method.
90       * @param value1  The value to apply the functions to, may be {@code null}.
91       * @param mapper1 The first function to apply, must not be {@code null}.
92       * @param mapper2 The second function to apply, must not be {@code null}.
93       * @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}.
94       * @see #applyNonNull(Object, Function)
95       * @see #applyNonNull(Object, Function, Function, Function)
96       * @since 3.19.0
97       */
98      public static <T, U, R> R applyNonNull(final T value1, final Function<? super T, ? extends U> mapper1, final Function<? super U, ? extends R> mapper2) {
99          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 }