java.util.function.Functions Maven / Gradle / Ivy
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package java.util.function;
import java.lang.reflect.Constructor;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Map;
/**
* This is the back-port for the according class of Java 1.8+.
*
* @author Joerg Hohwiller (hohwille at users.sourceforge.net)
* @since 1.0.0
*/
public final class Functions {
/**
* Construction prohibited.
*/
private Functions() {
}
/**
* @param is the generic type of the input and result of the function.
* @return a function whose {@link Function#apply(Object) apply} method returns the provided input.
*/
public static Function identity() {
return new Function() {
@Override
public T apply(T t) {
return t;
}
};
}
/**
* Returns a function which performs the first function followed by the second function.
*
* @param is the generic type for inputs to the first function.
* @param is the generic type for results from first function and inputs to the second function. May be
* the same type as {@code }.
* @param Type for results from the second function. May be the same type as * {@code }.
* @param first Initial function from {@code } to {@code }.
* @param second additional function from {@code } to {@code }.
* @return a function which performs the first function followed by the second function.
*/
public static Function chain(final Function super T, ? extends U> first,
final Function super U, ? extends R> second) {
if ((first == null) || (second == null)) {
throw new NullPointerException();
}
return new Function() {
@Override
public R apply(T t) {
return second.apply(first.apply(t));
}
};
}
/**
* Returns a constant output regardless of input.
*
* @param is the generic type of the (ignored) input to the function.
* @param is the generic type of the result.
*
* @param constant The value to be returned by the {@link Function#apply(Object) apply} method.
* @return a {@link Function} whose {@link Function#apply(Object) apply} method provides a constant result.
*/
public static Function constant(final R constant) {
return new Function() {
@Override
public R apply(T t) {
return constant;
}
};
}
/**
* A function that substitutes a single input value with a specified replacement. Input values are compared
* using {@code equals()}.
*
* @param The type of values.
* @param subOut The input value to be substituted out.
* @param subIn The replacement value for matching inputs.
* @return a {@link Function} that substitutes a single input value with a specified replacement.
*/
public static Function substitute(final T subOut, final T subIn) {
return new Function() {
@Override
public T apply(T t) {
// return (a == b) || (a != null && a.equals(b));
if ((subOut == t) || ((subOut != null) && (subOut.equals(t)))) {
return subIn;
}
return t;
}
};
}
/**
* Returns a new instance of {@code } constructed with provided {@code }.
*
* @param Type of output values from mapping
* @param Type of input values to mapping
* @param clazzT The {@code Class} which defines objects of type {@code }
* @param clazzR The {@code Class} which defines objects of type {@code }
* @return a {@link Function} which creates instances of {@code } using {@code } as the constructor
* parameter.
*/
public static Function instantiate(Class extends T> clazzT, Class extends R> clazzR) {
if ((clazzT == null) || (clazzR == null)) {
throw new NullPointerException();
}
final Constructor extends R> constructor;
try {
constructor = clazzR.getConstructor(clazzT);
} catch (NoSuchMethodException noConstructor) {
throw new IllegalArgumentException("no constructor for " + clazzR.getSimpleName() + "(" + clazzT.getSimpleName()
+ ")", noConstructor);
}
return new Function() {
/**
* {@inheritDoc}
*/
@Override
public R apply(T t) {
try {
return constructor.newInstance(t);
} catch (Exception ex) {
throw new UndeclaredThrowableException(ex);
}
}
};
}
/**
* Returns a function which maps inputs according to the provided mapping. Attempting to apply a value not
* from the given map will cause an {@code IllegalArgumentException} to be thrown. A copy is
* not made of the map. Care should be taken to avoid changes to the map during operation
* may produce results which violate the {@code apply} method contract.
*
* @param output type from mapping operation
* @param input type to mapping operation
* @param map provides the mappings from {@code } to {@code }
* @return the {@link Function} as described above.
*/
public static Function forMap(final Map super T, ? extends R> map) {
if (map == null) {
throw new NullPointerException();
}
return new Function() {
@Override
public R apply(T t) {
if (map.containsKey(t)) {
return map.get(t);
} else {
throw new IllegalArgumentException("unmappable : " + t);
}
}
};
}
/**
* Returns a function which maps inputs according to the provided mapping. The provided default value is
* returned for all {@code } keys not found in the map. A copy is not made of the apply
* and care should be taken to avoid changes to the apply during operation may produce results which violate
* the {@code apply} method contract.
*
* @param input type to mapping function
* @param output type from mapping function
* @param output type from mapping function
* @param mapping provides the mappings from {@code } to {@code }
* @param defaultValue the value returned by {@code apply} method for {@code } values not contained in
* the provided map.
* @return the {@link Function} as described above.
*/
public static Function forMap(final Map super T, RR> mapping, final RR defaultValue) {
if (mapping == null) {
throw new NullPointerException();
}
return new Function() {
/**
* {@inheritDoc}
*/
@Override
public R apply(T t) {
R result = mapping.get(t);
if ((result != null) || (mapping.containsKey(t))) {
return result;
} else {
return defaultValue;
}
}
};
}
/**
* Map according to the provided predicate. Two output values are provided {@code forTrue} is returned if
* the predicate returns {@code true} otherwise the {@code forFalse} value is returned.
*
* @param input type to mapping function
* @param output type from mapping function
* @param predicate decides which value {@code apply} method should return
* @param forTrue value to be returned for {@code true} predicate results
* @param forFalse value to be returned for {@code false} predicate results
* @return a Function whose {@code apply} method provides results according to the provided predicate.
*/
public static Function forPredicate(final Predicate super T> predicate, final R forTrue,
final R forFalse) {
if (predicate == null) {
throw new NullPointerException();
}
return new Function() {
@Override
public R apply(T t) {
return predicate.test(t) ? forTrue : forFalse;
}
};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy