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}