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 }