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 * http://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 */ 017package org.apache.juneau.commons.function; 018 019import static org.apache.juneau.commons.utils.AssertionUtils.*; 020 021import java.util.function.*; 022 023/** 024 * A functional interface representing a function that accepts five arguments and produces a result. 025 * 026 * <p> 027 * This interface extends the standard Java {@link java.util.function.Function} pattern to support 028 * five-argument functions. It's useful when you need to pass functions with five parameters to methods 029 * that expect functional interfaces, such as in stream operations, builders, or callback patterns. 030 * 031 * <h5 class='section'>Features:</h5> 032 * <ul class='spaced-list'> 033 * <li>Functional interface - can be used with lambda expressions and method references 034 * <li>Composition support - provides {@link #andThen(Function)} for function chaining 035 * <li>Type-safe - generic type parameters ensure compile-time type safety 036 * </ul> 037 * 038 * <h5 class='section'>Use Cases:</h5> 039 * <ul class='spaced-list'> 040 * <li>Five-argument transformations in functional programming patterns 041 * <li>Builder methods that accept five-parameter functions 042 * <li>Stream operations requiring five-argument functions 043 * <li>Callback patterns with five parameters 044 * </ul> 045 * 046 * <h5 class='section'>Usage:</h5> 047 * <p class='bjava'> 048 * <jc>// Lambda expression</jc> 049 * Function5<String,Integer,Boolean,Double,Long,String> <jv>format</jv> = (<jv>s</jv>, <jv>i</jv>, <jv>b</jv>, <jv>d</jv>, <jv>l</jv>) -> 050 * <jv>s</jv> + <js>"-"</js> + <jv>i</jv> + <js>"-"</js> + (<jv>b</jv> ? <js>"Y"</js> : <js>"N"</js>) + <js>"-"</js> + <jv>d</jv> + <js>"-"</js> + <jv>l</jv>; 051 * String <jv>result</jv> = <jv>format</jv>.apply(<js>"prefix"</js>, 42, <jk>true</jk>, 95.5, 1234567890L); 052 * 053 * <jc>// Function composition</jc> 054 * Function5<Integer,Integer,Integer,Integer,Integer,Integer> <jv>add</jv> = (<jv>a</jv>, <jv>b</jv>, <jv>c</jv>, <jv>d</jv>, <jv>e</jv>) -> <jv>a</jv> + <jv>b</jv> + <jv>c</jv> + <jv>d</jv> + <jv>e</jv>; 055 * Function5<Integer,Integer,Integer,Integer,Integer,String> <jv>addAndFormat</jv> = <jv>add</jv>.andThen(Object::toString); 056 * String <jv>sum</jv> = <jv>addAndFormat</jv>.apply(5, 3, 2, 1, 1); <jc>// Returns "12"</jc> 057 * </p> 058 * 059 * <h5 class='section'>See Also:</h5><ul> 060 * <li class='jc'>{@link Function2} - Two-argument function 061 * <li class='jc'>{@link Function3} - Three-argument function 062 * <li class='jc'>{@link Function4} - Four-argument function 063 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauCommonsBasics">juneau-commons Basics</a> 064 * </ul> 065 * 066 * @param <A> The type of the first argument to the function. 067 * @param <B> The type of the second argument to the function. 068 * @param <C> The type of the third argument to the function. 069 * @param <D> The type of the fourth argument to the function. 070 * @param <E> The type of the fifth argument to the function. 071 * @param <R> The type of the result of the function. 072 */ 073@FunctionalInterface 074public interface Function5<A,B,C,D,E,R> { 075 076 /** 077 * Returns a composed function that first applies this function to its input, and then applies 078 * the {@code after} function to the result. 079 * 080 * <p> 081 * This method enables function composition, allowing you to chain multiple transformations together. 082 * 083 * <h5 class='section'>Example:</h5> 084 * <p class='bjava'> 085 * Function5<Integer,Integer,Integer,Integer,Integer,Integer> <jv>multiply</jv> = (<jv>a</jv>, <jv>b</jv>, <jv>c</jv>, <jv>d</jv>, <jv>e</jv>) -> <jv>a</jv> * <jv>b</jv> * <jv>c</jv> * <jv>d</jv> * <jv>e</jv>; 086 * Function5<Integer,Integer,Integer,Integer,Integer,String> <jv>multiplyAndFormat</jv> = <jv>multiply</jv>.andThen(<jv>n</jv> -> <js>"Result: "</js> + <jv>n</jv>); 087 * String <jv>result</jv> = <jv>multiplyAndFormat</jv>.apply(2, 2, 2, 2, 2); <jc>// Returns "Result: 32"</jc> 088 * </p> 089 * 090 * @param <V> The type of output of the {@code after} function, and of the composed function. 091 * @param after The function to apply after this function is applied. Must not be <jk>null</jk>. 092 * @return A composed function that first applies this function and then applies the {@code after} function. 093 * @throws NullPointerException if {@code after} is <jk>null</jk>. 094 */ 095 default <V> Function5<A,B,C,D,E,V> andThen(Function<? super R,? extends V> after) { 096 assertArgNotNull("after", after); 097 return (A a, B b, C c, D d, E e) -> after.apply(apply(a, b, c, d, e)); 098 } 099 100 /** 101 * Applies this function to the given arguments. 102 * 103 * <h5 class='section'>Example:</h5> 104 * <p class='bjava'> 105 * Function5<String,Integer,Boolean,Double,Long,String> <jv>format</jv> = (<jv>s</jv>, <jv>n</jv>, <jv>upper</jv>, <jv>mult</jv>, <jv>time</jv>) -> { 106 * String <jv>result</jv> = <jv>s</jv>.repeat(<jv>n</jv>); 107 * <jv>result</jv> = <jv>upper</jv> ? <jv>result</jv>.toUpperCase() : <jv>result</jv>; 108 * <jk>return</jk> <jv>result</jv> + <js>" x"</js> + <jv>mult</jv> + <js>" @"</js> + <jv>time</jv>; 109 * }; 110 * String <jv>result</jv> = <jv>format</jv>.apply(<js>"ha"</js>, 2, <jk>true</jk>, 1.5, 1234567890L); 111 * </p> 112 * 113 * @param a The first function argument. 114 * @param b The second function argument. 115 * @param c The third function argument. 116 * @param d The fourth function argument. 117 * @param e The fifth function argument. 118 * @return The function result. 119 */ 120 R apply(A a, B b, C c, D d, E e); 121}