/*
 * Copyright (c) 2016 Goldman Sachs.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v. 1.0 which accompany this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 */

package org.eclipse.collections.impl.block.factory;

import java.util.Map;

import org.eclipse.collections.api.block.SerializableComparator;
import org.eclipse.collections.api.block.function.Function;
import org.eclipse.collections.api.block.function.Function2;
import org.eclipse.collections.api.block.function.primitive.BooleanFunction;
import org.eclipse.collections.api.block.function.primitive.ByteFunction;
import org.eclipse.collections.api.block.function.primitive.CharFunction;
import org.eclipse.collections.api.block.function.primitive.DoubleFunction;
import org.eclipse.collections.api.block.function.primitive.FloatFunction;
import org.eclipse.collections.api.block.function.primitive.IntFunction;
import org.eclipse.collections.api.block.function.primitive.LongFunction;
import org.eclipse.collections.api.block.function.primitive.ShortFunction;
import org.eclipse.collections.api.block.predicate.Predicate;
import org.eclipse.collections.api.block.procedure.Procedure;
import org.eclipse.collections.api.block.procedure.Procedure2;
import org.eclipse.collections.api.block.procedure.primitive.ObjectIntProcedure;
import org.eclipse.collections.api.tuple.Pair;
import org.eclipse.collections.impl.block.comparator.primitive.BooleanFunctionComparator;
import org.eclipse.collections.impl.block.comparator.primitive.ByteFunctionComparator;
import org.eclipse.collections.impl.block.comparator.primitive.CharFunctionComparator;
import org.eclipse.collections.impl.block.comparator.primitive.DoubleFunctionComparator;
import org.eclipse.collections.impl.block.comparator.primitive.FloatFunctionComparator;
import org.eclipse.collections.impl.block.comparator.primitive.IntFunctionComparator;
import org.eclipse.collections.impl.block.comparator.primitive.LongFunctionComparator;
import org.eclipse.collections.impl.block.comparator.primitive.ShortFunctionComparator;
import org.eclipse.collections.impl.block.function.CaseFunction;
import org.eclipse.collections.impl.block.function.IfFunction;
import org.eclipse.collections.impl.block.function.checked.CheckedFunction;
import org.eclipse.collections.impl.block.function.checked.ThrowingFunction;
import org.eclipse.collections.impl.block.function.primitive.IntegerFunctionImpl;
import org.eclipse.collections.impl.tuple.Tuples;
import org.eclipse.collections.impl.utility.Iterate;
import org.eclipse.collections.impl.utility.StringIterate;

public final class Functions
{
    private static final Function<Double, Double> DOUBLE_PASS_THRU_FUNCTION = new DoublePassThruFunction();
    private static final Function<Integer, Integer> INTEGER_PASS_THRU_FUNCTION = new IntegerPassThruFunction();
    private static final Function<Long, Long> LONG_PASS_THRU_FUNCTION = new LongPassThruFunction();

    private static final Function<Object, Boolean> TRUE_FUNCTION = new TrueFunction();
    private static final Function<Object, Boolean> FALSE_FUNCTION = new FalseFunction();
    private static final Function<?, ?> PASS_THRU_FUNCTION = new PassThruFunction<>();
    private static final Function<String, String> STRING_TRIM_FUNCTION = new StringTrimFunction();
    private static final Function<Object, Class<?>> CLASS_FUNCTION = new ClassFunction();
    private static final Function<Number, Double> MATH_SIN_FUNCTION = new MathSinFunction();
    private static final Function<Integer, Integer> SQUARED_INTEGER = new SquaredIntegerFunction();
    private static final Function<Object, String> TO_STRING_FUNCTION = new ToStringFunction();
    private static final Function<String, Integer> STRING_TO_INTEGER_FUNCTION = new StringToIntegerFunction();
    private static final Function<?, ?> MAP_KEY_FUNCTION = new MapKeyFunction<>();
    private static final Function<?, ?> MAP_VALUE_FUNCTION = new MapValueFunction<>();
    private static final Function<Iterable<?>, Integer> SIZE_FUNCTION = new SizeFunction();
    private static final FirstOfPairFunction<?> FIRST_OF_PAIR_FUNCTION = new FirstOfPairFunction<>();
    private static final SecondOfPairFunction<?> SECOND_OF_PAIR_FUNCTION = new SecondOfPairFunction<>();
    private static final CheckedFunction<String, Class<?>> CLASS_FOR_NAME = new ClassForNameFunction();
    private static final SwappedPairFunction<?, ?> SWAPPED_PAIR_FUNCTION = new SwappedPairFunction<>();

    private Functions()
    {
        throw new AssertionError("Suppress default constructor for noninstantiability");
    }

    private static class PassThruFunction<T> implements Function<T, T>
    {
        private static final long serialVersionUID = 1L;

        @Override
        public T valueOf(T anObject)
        {
            return anObject;
        }
    }

    private static class StringTrimFunction implements Function<String, String>
    {
        private static final long serialVersionUID = 1L;

        @Override
        public String valueOf(String s)
        {
            return s.trim();
        }
    }

    private static final class FixedValueFunction<T, V> implements Function<T, V>
    {
        private static final long serialVersionUID = 1L;
        private final V value;

        private FixedValueFunction(V value)
        {
            this.value = value;
        }

        @Override
        public V valueOf(T object)
        {
            return this.value;
        }
    }

    private static final class ClassFunction implements Function<Object, Class<?>>
    {
        private static final long serialVersionUID = 1L;

        @Override
        public Class<?> valueOf(Object anObject)
        {
            return anObject.getClass();
        }

        @Override
        public String toString()
        {
            return "object.getClass()";
        }
    }

    private static final class MathSinFunction implements Function<Number, Double>
    {
        private static final long serialVersionUID = 1L;

        @Override
        public Double valueOf(Number number)
        {
            return Math.sin(number.doubleValue());
        }

        @Override
        public String toString()
        {
            return "Math.sin()";
        }
    }

    private static final class SquaredIntegerFunction implements Function<Integer, Integer>
    {
        private static final long serialVersionUID = 1L;

        @Override
        public Integer valueOf(Integer value)
        {
            return value * value;
        }
    }

    private static final class ToStringFunction implements Function<Object, String>
    {
        private static final long serialVersionUID = 1L;

        @Override
        public String valueOf(Object anObject)
        {
            return String.valueOf(anObject);
        }

        @Override
        public String toString()
        {
            return "toString";
        }
    }

    private static final class StringToIntegerFunction implements Function<String, Integer>
    {
        private static final long serialVersionUID = 1L;

        @Override
        public Integer valueOf(String string)
        {
            return Integer.valueOf(string);
        }

        @Override
        public String toString()
        {
            return "stringToInteger";
        }
    }

    
Allows a lambda or anonymous inner class that needs to throw a checked exception to be safely wrapped as a Function that will throw a RuntimeException, wrapping the checked exception that is the cause.
/** * Allows a lambda or anonymous inner class that needs to throw a checked exception to be safely wrapped as a * Function that will throw a RuntimeException, wrapping the checked exception that is the cause. */
public static <T, V> Function<T, V> throwing(ThrowingFunction<T, V> throwingFunction) { return new ThrowingFunctionAdapter<>(throwingFunction); }
Allows a lambda or anonymous inner class that needs to throw a checked exception to be safely wrapped as a Function that will throw a user specified RuntimeException based on the provided function. The function is passed the current element and the checked exception that was thrown as context arguments.
/** * Allows a lambda or anonymous inner class that needs to throw a checked exception to be safely wrapped as a * Function that will throw a user specified RuntimeException based on the provided function. The function * is passed the current element and the checked exception that was thrown as context arguments. */
public static <T, V> Function<T, V> throwing( ThrowingFunction<T, V> throwingFunction, Function2<T, ? super Throwable, ? extends RuntimeException> rethrow) { return each -> { try { return throwingFunction.safeValueOf(each); } catch (RuntimeException e) { throw e; } catch (Throwable t) { throw rethrow.value(each, t); } }; }
Allows a Java 8 lambda and method reference to be used in a method taking a Function as a parameter without any ambiguity.
/** * Allows a Java 8 lambda and method reference to be used in a method taking a Function as a parameter * without any ambiguity. */
public static <T, V> Function<T, V> cast(Function<T, V> function) { return function; }
Alias for identity(). Inlineable.
See Also:
  • identity()
/** * Alias for identity(). Inlineable. * * @see #identity() */
public static <T> Function<T, T> getPassThru() { return Functions.identity(); }
Since:6.0
/** * @since 6.0 */
public static <T> Function<T, T> identity() { return (Function<T, T>) PASS_THRU_FUNCTION; }
Since:6.0
/** * @since 6.0 */
public static Function<Object, Boolean> getTrue() { return TRUE_FUNCTION; }
Since:6.0
/** * @since 6.0 */
public static Function<Object, Boolean> getFalse() { return FALSE_FUNCTION; } public static <T, V> Function<T, V> getFixedValue(V value) { return new FixedValueFunction<>(value); } public static Function<Object, Class<?>> getToClass() { return CLASS_FUNCTION; } public static Function<Number, Double> getMathSinFunction() { return MATH_SIN_FUNCTION; } public static Function<Number, Number> getNumberPassThru() { return (Function<Number, Number>) PASS_THRU_FUNCTION; } public static Function<Integer, Integer> getIntegerPassThru() { return INTEGER_PASS_THRU_FUNCTION; } public static Function<Long, Long> getLongPassThru() { return LONG_PASS_THRU_FUNCTION; } public static Function<Double, Double> getDoublePassThru() { return DOUBLE_PASS_THRU_FUNCTION; } public static Function<String, String> getStringPassThru() { return (Function<String, String>) PASS_THRU_FUNCTION; } public static Function<String, String> getStringTrim() { return STRING_TRIM_FUNCTION; } public static Function<Object, String> getToString() { return TO_STRING_FUNCTION; } public static Function<Object, String> getNullSafeToString(String defaultValue) { return Functions.nullSafe(TO_STRING_FUNCTION, defaultValue); } public static <T> SerializableComparator<T> toBooleanComparator(BooleanFunction<T> function) { return new BooleanFunctionComparator<>(function); } public static <T> SerializableComparator<T> toByteComparator(ByteFunction<T> function) { return new ByteFunctionComparator<>(function); } public static <T> SerializableComparator<T> toCharComparator(CharFunction<T> function) { return new CharFunctionComparator<>(function); } public static <T> SerializableComparator<T> toFloatComparator(FloatFunction<T> function) { return new FloatFunctionComparator<>(function); } public static <T> SerializableComparator<T> toShortComparator(ShortFunction<T> function) { return new ShortFunctionComparator<>(function); } public static <T> SerializableComparator<T> toIntComparator(IntFunction<T> function) { return new IntFunctionComparator<>(function); } public static <T> SerializableComparator<T> toDoubleComparator(DoubleFunction<T> function) { return new DoubleFunctionComparator<>(function); } public static <T> SerializableComparator<T> toLongComparator(LongFunction<T> function) { return new LongFunctionComparator<>(function); } public static Function<String, Integer> getStringToInteger() { return STRING_TO_INTEGER_FUNCTION; } public static <T, V> Function<T, V> withDefault(Function<? super T, ? extends V> function, V defaultValue) { return new DefaultFunction<>(function, defaultValue); } public static <T, V> Function<T, V> nullSafe(Function<? super T, ? extends V> function) { return new NullSafeFunction<>(function, null); } public static <T, V> Function<T, V> nullSafe(Function<? super T, ? extends V> function, V nullValue) { return new NullSafeFunction<>(function, nullValue); } public static <V1> Function<Pair<V1, ?>, V1> firstOfPair() { return (Function<Pair<V1, ?>, V1>) (Function<?, ?>) FIRST_OF_PAIR_FUNCTION; } public static <V2> Function<Pair<?, V2>, V2> secondOfPair() { return (Function<Pair<?, V2>, V2>) (Function<?, ?>) SECOND_OF_PAIR_FUNCTION; }
Swap the input pair and return the swapped pair.
Returns:A function that gets the swapped pair Iterable
/** * Swap the input pair and return the swapped pair. * * @return A function that gets the swapped pair {@code Iterable} */
public static <S, T> Function<Pair<S, T>, Pair<T, S>> swappedPair() { return (Function<Pair<S, T>, Pair<T, S>>) (Function<?, ?>) SWAPPED_PAIR_FUNCTION; }
Bind the parameter passed to a Function2 into a new Function.
Params:
  • function – The Function2 to delegate the invocation to.
  • parameter – The parameter the use in the invocation of the delegate function.
Returns:A new Function
/** * Bind the parameter passed to a Function2 into a new Function. * * @param function The Function2 to delegate the invocation to. * @param parameter The parameter the use in the invocation of the delegate function. * @return A new Function */
public static <T, P, R> Function<T, R> bind(Function2<? super T, ? super P, ? extends R> function, P parameter) { return new BindFunction2<>(function, parameter); }
Bind the input of a Procedure to the result of an function, returning a new Procedure.
Params:
  • delegate – The Procedure to delegate the invocation to.
  • function – The Function that will create the input for the delegate
Returns:A new Procedure
/** * Bind the input of a Procedure to the result of an function, returning a new Procedure. * * @param delegate The Procedure to delegate the invocation to. * @param function The Function that will create the input for the delegate * @return A new Procedure */
public static <T1, T2> Procedure<T1> bind( Procedure<? super T2> delegate, Function<? super T1, T2> function) { return new BindProcedure<>(delegate, function); }
Bind the input of a ObjectIntProcedure to the result of an function, returning a new ObjectIntProcedure.
Params:
  • delegate – The ObjectIntProcedure to delegate the invocation to.
  • function – The Function that will create the input for the delegate
Returns:A new ObjectIntProcedure
/** * Bind the input of a ObjectIntProcedure to the result of an function, returning a new ObjectIntProcedure. * * @param delegate The ObjectIntProcedure to delegate the invocation to. * @param function The Function that will create the input for the delegate * @return A new ObjectIntProcedure */
public static <T1, T2> ObjectIntProcedure<T1> bind( ObjectIntProcedure<? super T2> delegate, Function<? super T1, T2> function) { return new BindObjectIntProcedure<>(delegate, function); }
Bind the input of the first argument of a Procedure2 to the result of an function, returning a new Procedure2.
Params:
  • delegate – The Procedure2 to delegate the invocation to.
  • function – The Function that will create the input for the delegate
Returns:A new Procedure2
/** * Bind the input of the first argument of a Procedure2 to the result of an function, returning a new Procedure2. * * @param delegate The Procedure2 to delegate the invocation to. * @param function The Function that will create the input for the delegate * @return A new Procedure2 */
public static <T1, T2, T3> Procedure2<T1, T3> bind( Procedure2<? super T2, T3> delegate, Function<? super T1, T2> function) { return new BindProcedure2<>(delegate, function); } public static Function<Integer, Integer> squaredInteger() { return SQUARED_INTEGER; } public static <T, V> Function<T, V> firstNotNullValue(Function<T, V>... functions) { return new FirstNotNullFunction<>(functions); } public static <T> Function<T, String> firstNotEmptyStringValue( Function<T, String>... functions) { return new FirstNotEmptyStringFunction<>(functions); } public static <T1, T2, I extends Iterable<T2>> Function<T1, I> firstNotEmptyCollectionValue( Function<T1, I>... functions) { return new FirstNotEmptyCollectionFunction<>(functions); } public static <T, V> Function<T, V> ifTrue( Predicate<? super T> predicate, Function<? super T, ? extends V> function) { return new IfFunction<>(predicate, function); } public static <T, V> Function<T, V> ifElse( Predicate<? super T> predicate, Function<? super T, ? extends V> trueFunction, Function<? super T, ? extends V> falseFunction) { return new IfFunction<>(predicate, trueFunction, falseFunction); } public static <T extends Comparable<? super T>, V> CaseFunction<T, V> caseDefault( Function<? super T, ? extends V> defaultFunction) { return new CaseFunction<T, V>(defaultFunction); } public static <T extends Comparable<? super T>, V> CaseFunction<T, V> caseDefault( Function<? super T, ? extends V> defaultFunction, Predicate<? super T> predicate, Function<? super T, ? extends V> function) { CaseFunction<T, V> caseFunction = Functions.<T, V>caseDefault(defaultFunction); return caseFunction.addCase(predicate, function); } public static <T, V> Function<T, V> synchronizedEach(Function<T, V> function) { return new SynchronizedFunction<>(function); } public static Function<String, Class<?>> classForName() { return CLASS_FOR_NAME; } private static final class FirstNotNullFunction<T, V> implements Function<T, V> { private static final long serialVersionUID = 1L; private final Function<T, V>[] functions; private FirstNotNullFunction(Function<T, V>... functions) { this.functions = functions; } @Override public V valueOf(T object) { for (Function<T, V> function : this.functions) { V result = function.valueOf(object); if (result != null) { return result; } } return null; } } private static final class FirstNotEmptyStringFunction<T> implements Function<T, String> { private static final long serialVersionUID = 1L; private final Function<T, String>[] functions; private FirstNotEmptyStringFunction(Function<T, String>... functions) { this.functions = functions; } @Override public String valueOf(T object) { for (Function<T, String> function : this.functions) { String result = function.valueOf(object); if (StringIterate.notEmpty(result)) { return result; } } return null; } } private static final class FirstNotEmptyCollectionFunction<T1, T2, I extends Iterable<T2>> implements Function<T1, I> { private static final long serialVersionUID = 1L; private final Function<T1, I>[] functions; private FirstNotEmptyCollectionFunction(Function<T1, I>[] functions) { this.functions = functions; } @Override public I valueOf(T1 object) { for (Function<T1, I> function : this.functions) { I result = function.valueOf(object); if (Iterate.notEmpty(result)) { return result; } } return null; } } private static final class SynchronizedFunction<T, V> implements Function<T, V> { private static final long serialVersionUID = 1L; private final Function<T, V> function; private SynchronizedFunction(Function<T, V> function) { this.function = function; } @Override public V valueOf(T each) { synchronized (each) { return this.function.valueOf(each); } } } public static <T1, T2, T3> FunctionChain<T1, T2, T3> chain(Function<T1, T2> function1, Function<? super T2, T3> function2) { return new FunctionChain<>(function1, function2); } public static <T1, T2> BooleanFunctionChain<T1, T2> chainBoolean(Function<T1, T2> function1, BooleanFunction<? super T2> function2) { return new BooleanFunctionChain<>(function1, function2); } public static <T1, T2> ByteFunctionChain<T1, T2> chainByte(Function<T1, T2> function1, ByteFunction<? super T2> function2) { return new ByteFunctionChain<>(function1, function2); } public static <T1, T2> CharFunctionChain<T1, T2> chainChar(Function<T1, T2> function1, CharFunction<? super T2> function2) { return new CharFunctionChain<>(function1, function2); } public static <T1, T2> DoubleFunctionChain<T1, T2> chainDouble(Function<T1, T2> function1, DoubleFunction<? super T2> function2) { return new DoubleFunctionChain<>(function1, function2); } public static <T1, T2> FloatFunctionChain<T1, T2> chainFloat(Function<T1, T2> function1, FloatFunction<? super T2> function2) { return new FloatFunctionChain<>(function1, function2); } public static <T1, T2> IntFunctionChain<T1, T2> chainInt(Function<T1, T2> function1, IntFunction<? super T2> function2) { return new IntFunctionChain<>(function1, function2); } public static <T1, T2> LongFunctionChain<T1, T2> chainLong(Function<T1, T2> function1, LongFunction<? super T2> function2) { return new LongFunctionChain<>(function1, function2); } public static <T1, T2> ShortFunctionChain<T1, T2> chainShort(Function<T1, T2> function1, ShortFunction<? super T2> function2) { return new ShortFunctionChain<>(function1, function2); } private static class DoublePassThruFunction implements Function<Double, Double>, DoubleFunction<Double> { private static final long serialVersionUID = 1L; @Override public double doubleValueOf(Double each) { return each.doubleValue(); } @Override public Double valueOf(Double each) { return each; } @Override public String toString() { return DoublePassThruFunction.class.getSimpleName(); } } private static class IntegerPassThruFunction implements Function<Integer, Integer>, IntFunction<Integer> { private static final long serialVersionUID = 1L; @Override public int intValueOf(Integer each) { return each.intValue(); } @Override public Integer valueOf(Integer each) { return each; } @Override public String toString() { return IntegerPassThruFunction.class.getSimpleName(); } } private static class LongPassThruFunction implements Function<Long, Long>, LongFunction<Long> { private static final long serialVersionUID = 1L; @Override public long longValueOf(Long each) { return each.longValue(); } @Override public Long valueOf(Long each) { return each; } @Override public String toString() { return LongPassThruFunction.class.getSimpleName(); } } private static final class DefaultFunction<T, V> implements Function<T, V> { private static final long serialVersionUID = 1L; private final Function<? super T, ? extends V> function; private final V defaultValue; private DefaultFunction(Function<? super T, ? extends V> newFunction, V newDefaultValue) { this.function = newFunction; this.defaultValue = newDefaultValue; } @Override public V valueOf(T anObject) { V returnValue = this.function.valueOf(anObject); if (returnValue == null) { return this.defaultValue; } return returnValue; } } private static final class NullSafeFunction<T, V> implements Function<T, V> { private static final long serialVersionUID = 1L; private final Function<? super T, ? extends V> function; private final V nullValue; private NullSafeFunction(Function<? super T, ? extends V> function, V nullValue) { this.function = function; this.nullValue = nullValue; } @Override public V valueOf(T object) { return object == null ? this.nullValue : this.function.valueOf(object); } } public static <T, V1, V2> Function<T, Pair<V1, V2>> pair( Function<? super T, V1> function1, Function<? super T, V2> function2) { return t -> Tuples.pair(function1.valueOf(t), function2.valueOf(t)); }
Returns:A function that gets the key out of a Entry
/** * @return A function that gets the key out of a {@link java.util.Map.Entry} */
@SuppressWarnings("UnnecessaryFullyQualifiedName") public static <K> Function<Map.Entry<K, ?>, K> getKeyFunction() { return (Function<Map.Entry<K, ?>, K>) MAP_KEY_FUNCTION; }
Returns:A function that gets the value out of a Entry
/** * @return A function that gets the value out of a {@link java.util.Map.Entry} */
@SuppressWarnings("UnnecessaryFullyQualifiedName") public static <V> Function<Map.Entry<?, V>, V> getValueFunction() { return (Function<Map.Entry<?, V>, V>) MAP_VALUE_FUNCTION; } private static class MapKeyFunction<K> implements Function<Map.Entry<K, ?>, K> { private static final long serialVersionUID = 1L; @Override public K valueOf(Map.Entry<K, ?> entry) { return entry.getKey(); } } private static class MapValueFunction<V> implements Function<Map.Entry<?, V>, V> { private static final long serialVersionUID = 1L; @Override public V valueOf(Map.Entry<?, V> entry) { return entry.getValue(); } }
Returns:A function that gets the size of an Iterable
/** * @return A function that gets the size of an {@code Iterable} */
public static Function<Iterable<?>, Integer> getSizeOf() { return SIZE_FUNCTION; } public static class SizeFunction extends IntegerFunctionImpl<Iterable<?>> { private static final long serialVersionUID = 1L; @Override public int intValueOf(Iterable<?> iterable) { return Iterate.sizeOf(iterable); } } public static final class FunctionChain<T1, T2, T3> implements Function<T1, T3> { private static final long serialVersionUID = 1L; private final Function<T1, T2> function1; private final Function<? super T2, T3> function2; private FunctionChain(Function<T1, T2> function1, Function<? super T2, T3> function2) { this.function1 = function1; this.function2 = function2; } @Override public T3 valueOf(T1 object) { return this.function2.valueOf(this.function1.valueOf(object)); } public <T4> FunctionChain<T1, T3, T4> chain(Function<? super T3, T4> function) { return new FunctionChain<>(this, function); } public BooleanFunctionChain<T1, T3> chainBoolean(BooleanFunction<? super T3> function) { return new BooleanFunctionChain<>(this, function); } public ByteFunctionChain<T1, T3> chainByte(ByteFunction<? super T3> function) { return new ByteFunctionChain<>(this, function); } public CharFunctionChain<T1, T3> chainChar(CharFunction<? super T3> function) { return new CharFunctionChain<>(this, function); } public DoubleFunctionChain<T1, T3> chainDouble(DoubleFunction<? super T3> function) { return new DoubleFunctionChain<>(this, function); } public FloatFunctionChain<T1, T3> chainFloat(FloatFunction<? super T3> function) { return new FloatFunctionChain<>(this, function); } public IntFunctionChain<T1, T3> chainInt(IntFunction<? super T3> function) { return new IntFunctionChain<>(this, function); } public LongFunctionChain<T1, T3> chainLong(LongFunction<? super T3> function) { return new LongFunctionChain<>(this, function); } public ShortFunctionChain<T1, T3> chainShort(ShortFunction<? super T3> function) { return new ShortFunctionChain<>(this, function); } } public static final class BooleanFunctionChain<T1, T2> implements BooleanFunction<T1> { private static final long serialVersionUID = 1L; private final Function<T1, T2> function1; private final BooleanFunction<? super T2> function2; private BooleanFunctionChain(Function<T1, T2> function1, BooleanFunction<? super T2> function2) { this.function1 = function1; this.function2 = function2; } @Override public boolean booleanValueOf(T1 object) { return this.function2.booleanValueOf(this.function1.valueOf(object)); } } public static final class ByteFunctionChain<T1, T2> implements ByteFunction<T1> { private static final long serialVersionUID = 1L; private final Function<T1, T2> function1; private final ByteFunction<? super T2> function2; private ByteFunctionChain(Function<T1, T2> function1, ByteFunction<? super T2> function2) { this.function1 = function1; this.function2 = function2; } @Override public byte byteValueOf(T1 object) { return this.function2.byteValueOf(this.function1.valueOf(object)); } } public static final class CharFunctionChain<T1, T2> implements CharFunction<T1> { private static final long serialVersionUID = 1L; private final Function<T1, T2> function1; private final CharFunction<? super T2> function2; private CharFunctionChain(Function<T1, T2> function1, CharFunction<? super T2> function2) { this.function1 = function1; this.function2 = function2; } @Override public char charValueOf(T1 object) { return this.function2.charValueOf(this.function1.valueOf(object)); } } public static final class DoubleFunctionChain<T1, T2> implements DoubleFunction<T1> { private static final long serialVersionUID = 1L; private final Function<T1, T2> function1; private final DoubleFunction<? super T2> function2; private DoubleFunctionChain(Function<T1, T2> function1, DoubleFunction<? super T2> function2) { this.function1 = function1; this.function2 = function2; } @Override public double doubleValueOf(T1 object) { return this.function2.doubleValueOf(this.function1.valueOf(object)); } } public static final class FloatFunctionChain<T1, T2> implements FloatFunction<T1> { private static final long serialVersionUID = 1L; private final Function<T1, T2> function1; private final FloatFunction<? super T2> function2; private FloatFunctionChain(Function<T1, T2> function1, FloatFunction<? super T2> function2) { this.function1 = function1; this.function2 = function2; } @Override public float floatValueOf(T1 object) { return this.function2.floatValueOf(this.function1.valueOf(object)); } } public static final class IntFunctionChain<T1, T2> implements IntFunction<T1> { private static final long serialVersionUID = 1L; private final Function<T1, T2> function1; private final IntFunction<? super T2> function2; private IntFunctionChain(Function<T1, T2> function1, IntFunction<? super T2> function2) { this.function1 = function1; this.function2 = function2; } @Override public int intValueOf(T1 object) { return this.function2.intValueOf(this.function1.valueOf(object)); } } public static final class LongFunctionChain<T1, T2> implements LongFunction<T1> { private static final long serialVersionUID = 1L; private final Function<T1, T2> function1; private final LongFunction<? super T2> function2; private LongFunctionChain(Function<T1, T2> function1, LongFunction<? super T2> function2) { this.function1 = function1; this.function2 = function2; } @Override public long longValueOf(T1 object) { return this.function2.longValueOf(this.function1.valueOf(object)); } } public static final class ShortFunctionChain<T1, T2> implements ShortFunction<T1> { private static final long serialVersionUID = 1L; private final Function<T1, T2> function1; private final ShortFunction<? super T2> function2; private ShortFunctionChain(Function<T1, T2> function1, ShortFunction<? super T2> function2) { this.function1 = function1; this.function2 = function2; } @Override public short shortValueOf(T1 object) { return this.function2.shortValueOf(this.function1.valueOf(object)); } } private static class FirstOfPairFunction<T> implements Function<Pair<T, ?>, T> { private static final long serialVersionUID = 1L; @Override public T valueOf(Pair<T, ?> pair) { return pair.getOne(); } } private static class SecondOfPairFunction<T> implements Function<Pair<?, T>, T> { private static final long serialVersionUID = 1L; @Override public T valueOf(Pair<?, T> pair) { return pair.getTwo(); } } private static class ClassForNameFunction extends CheckedFunction<String, Class<?>> { private static final long serialVersionUID = 1L; @Override public Class<?> safeValueOf(String className) throws ClassNotFoundException { return Class.forName(className); } } private static final class BindObjectIntProcedure<T1, T2> implements ObjectIntProcedure<T1> { private static final long serialVersionUID = 1L; private final ObjectIntProcedure<? super T2> delegate; private final Function<? super T1, T2> function; private BindObjectIntProcedure(ObjectIntProcedure<? super T2> delegate, Function<? super T1, T2> function) { this.delegate = delegate; this.function = function; } @Override public void value(T1 each, int index) { this.delegate.value(this.function.valueOf(each), index); } } private static final class BindProcedure<T1, T2> implements Procedure<T1> { private static final long serialVersionUID = 1L; private final Procedure<? super T2> delegate; private final Function<? super T1, T2> function; private BindProcedure(Procedure<? super T2> delegate, Function<? super T1, T2> function) { this.delegate = delegate; this.function = function; } @Override public void value(T1 each) { this.delegate.value(this.function.valueOf(each)); } } private static final class BindProcedure2<T1, T2, T3> implements Procedure2<T1, T3> { private static final long serialVersionUID = 1L; private final Procedure2<? super T2, T3> delegate; private final Function<? super T1, T2> function; private BindProcedure2(Procedure2<? super T2, T3> delegate, Function<? super T1, T2> function) { this.delegate = delegate; this.function = function; } @Override public void value(T1 each, T3 constant) { this.delegate.value(this.function.valueOf(each), constant); } } private static final class BindFunction2<T1, T2, T3> implements Function<T1, T3> { private static final long serialVersionUID = 1L; private final Function2<? super T1, ? super T2, ? extends T3> delegate; private final T2 parameter; private BindFunction2(Function2<? super T1, ? super T2, ? extends T3> delegate, T2 parameter) { this.delegate = delegate; this.parameter = parameter; } @Override public T3 valueOf(T1 object) { return this.delegate.value(object, this.parameter); } } private static class SwappedPairFunction<S, T> implements Function<Pair<S, T>, Pair<T, S>> { private static final long serialVersionUID = 1L; @Override public Pair<T, S> valueOf(Pair<S, T> pair) { return pair.swap(); } } private static final class ThrowingFunctionAdapter<T, V> extends CheckedFunction<T, V> { private static final long serialVersionUID = 1L; private final ThrowingFunction<T, V> throwingFunction; private ThrowingFunctionAdapter(ThrowingFunction<T, V> throwingFunction) { this.throwingFunction = throwingFunction; } @Override public V safeValueOf(T object) throws Exception { return this.throwingFunction.safeValueOf(object); } } private static class TrueFunction implements Function<Object, Boolean> { private static final long serialVersionUID = 1L; @Override public Boolean valueOf(Object object) { return Boolean.TRUE; } } private static class FalseFunction implements Function<Object, Boolean> { private static final long serialVersionUID = 1L; @Override public Boolean valueOf(Object object) { return Boolean.FALSE; } } }