All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.yetamine.lang.functional.Acceptor Maven / Gradle / Ivy

The newest version!
/*
 * 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.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * A generic operation interface which is a convenient extension of the common
 * {@link Consumer} interface.
 *
 * @param 
 *            the type of the input to the operation
 */
@FunctionalInterface
public interface Acceptor extends Consumer {

    /**
     * Performs this operation on the given argument.
     *
     * 

* This method provides a direct bridge to {@link Function}, but this * interface intentionally does not inherit from it, because it has a * different role and function composition is not well-suited for it. * * @param t * the input argument * * @return the input argument */ default T apply(T t) { accept(t); return t; } /** * @see java.util.function.Consumer#andThen(Consumer) */ default Acceptor andThen(Consumer after) { Objects.requireNonNull(after); return t -> { accept(t); after.accept(t); }; } /** * Returns a consumer that executes this consumer only if the given * predicate is satisfied for the actual argument. * * @param predicate * the predicate to test the argument. It must not be * {@code null}. * * @return a consumer guarded by the predicate */ default Acceptor onlyIf(Predicate predicate) { Objects.requireNonNull(predicate); return t -> { if (predicate.test(t)) { accept(t); } }; } /** * Returns a function that performs, in sequence, this operation followed * applying the specified mapping function on the argument. * *

* To turn this instance in an usual {@link Function} instance without any * change of the result, use {@link Function#identity()} as the argument. * * @param * the type of the mapping result * @param mapping * the mapping function to apply. It must not be {@code null}. * * @return the composed function */ default Function finish(Function mapping) { Objects.requireNonNull(mapping); return t -> mapping.apply(apply(t)); } /** * Makes an instance from the given consumer. * *

* This method is a convenient factory method for adapting a consumer into * this smarter interface with fluent chaining with no casting-like steps, * or intermediate variables: * *

     * Acceptor.from(MyUtilities::someOperation).onlyIf(MyUtilities::someTest)
     * 
* * @param * the type of the argument * @param consumer * the consumer to adapt. It must not be {@code null}. * * @return the adapted consumer */ static Acceptor from(Consumer consumer) { return consumer::accept; } /** * Returns a nothing-doing instance. * * @param * the type of the argument * * @return the nothing-doing instance */ static Acceptor nil() { return NoOperation::execute; } /** * Returns an instance that applies, in sequence, all given consumers. * *

* 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 {@link Consumer#andThen(Consumer)} * causes too deep call nesting. * * @param * the type of the input to 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 Acceptor sequential(Iterable> sequence) { Objects.requireNonNull(sequence); return t -> { for (Consumer consumer : sequence) { consumer.accept(t); } }; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy