![JAR search and dependency download from the Maven repository](/logo.png)
net.yetamine.lang.functional.UnaryOperation Maven / Gradle / Ivy
Show all versions of net.yetamine.lang Show documentation
/*
* Copyright 2016 Yetamine
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.yetamine.lang.functional;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
/**
* A generic operation interface which is a convenient extension of the common
* {@link UnaryOperator} interface.
*
* @param
* the type of the input and output of the operation
*/
@FunctionalInterface
public interface UnaryOperation extends UnaryOperator {
/**
* Returns an operation that returns the result of the given function
* applied on the result of this operation.
*
* @param after
* the function to apply. It must not be {@code null}.
*
* @return the composition of the functions
*
* @see java.util.function.Function#andThen(Function)
*/
default UnaryOperation andNext(Function super T, ? extends T> after) {
Objects.requireNonNull(after);
return t -> after.apply(apply(t));
}
/**
* Returns an operation that executes this operation only if the given
* predicate is satisfied for the actual argument; if the predicate is
* unsatisfied, the operand is returned without as it is.
*
* @param predicate
* the predicate to test the argument. It must not be
* {@code null}.
*
* @return a consumer guarded by the predicate
*/
default UnaryOperation onlyIf(Predicate super T> predicate) {
Objects.requireNonNull(predicate);
return t -> predicate.test(t) ? apply(t) : t;
}
/**
* Makes an instance from the given function.
*
*
* This method is a convenient factory method for adapting a function into
* this smarter interface with fluent chaining with no casting-like steps,
* or intermediate variables:
*
*
* UnaryOperation.from(MyUtilities::someOperation).onlyIf(MyUtilities::someTest)
*
*
* @param
* the type of the argument
* @param operator
* the operator to adapt. It must not be {@code null}.
*
* @return the adapted operator
*/
static UnaryOperation from(Function super T, ? extends T> operator) {
return operator::apply;
}
/**
* Returns an operation that always returns its input argument.
*
* @param
* the type of the input and output of the operation
*
* @return a unary operation that always returns its input argument
*/
static UnaryOperation identity() {
return t -> t;
}
/**
* Returns an operation that applies, in sequence, all given functions as if
* they were composed, passing the result of the previous one as the
* argument to the next.
*
*
* This method does not make any copy of the input, therefore the caller may
* provide a dynamic underlying sequence, but on the other hand, the caller
* is responsible for thread safety of the sequence, so that another thread
* may iterate through the sequence, having a consistent snapshot.
*
*
*
* This method may be useful in the cases of a dynamic chain or when simply
* the sequence is long and chaining composition causes too deep call
* nesting.
*
* @param
* the type of the input and output of the operation
* @param sequence
* the sequence of the consumers to apply. It must not be
* {@code null} and it must not provide {@code null} elements.
*
* @return a consumer that applies, in sequence, all given consumers
*/
static UnaryOperation sequential(Iterable extends Function super T, ? extends T>> sequence) {
Objects.requireNonNull(sequence);
return t -> {
T result = t;
for (Function super T, ? extends T> function : sequence) {
result = function.apply(result);
}
return result;
};
}
}