Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.dm.jrt.function.Functions Maven / Gradle / Ivy
/*
* 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 com.github.dm.jrt.function;
import com.github.dm.jrt.channel.ResultChannel;
import com.github.dm.jrt.channel.RoutineException;
import com.github.dm.jrt.invocation.CommandInvocation;
import com.github.dm.jrt.invocation.FilterInvocation;
import com.github.dm.jrt.invocation.FunctionInvocation;
import com.github.dm.jrt.invocation.Invocation;
import com.github.dm.jrt.invocation.InvocationFactory;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
/**
* Utility class supporting functional programming.
*
* Created by davide-maestroni on 09/21/2015.
*/
public class Functions {
private static final BiConsumerWrapper, ?> sBiSink =
wrapBiConsumer(new BiConsumer() {
public void accept(final Object in1, final Object in2) {}
});
private static final FunctionWrapper, ?> sIdentity =
wrapFunction(new Function() {
public Object apply(final Object in) {
return in;
}
});
private static final BiFunctionWrapper, ?, ?> sFirst =
wrapBiFunction(new BiFunction() {
public Object apply(final Object in1, final Object in2) {
return in1;
}
});
private static final PredicateWrapper> sNegative = wrapPredicate(new Predicate() {
public boolean test(final Object o) {
return false;
}
});
private static final PredicateWrapper> sNotNull = wrapPredicate(new Predicate() {
public boolean test(final Object o) {
return (o != null);
}
});
private static final PredicateWrapper> sIsNull = sNotNull.negate();
private static final PredicateWrapper> sPositive = sNegative.negate();
private static final BiFunctionWrapper, ?, ?> sSecond =
wrapBiFunction(new BiFunction() {
public Object apply(final Object in1, final Object in2) {
return in2;
}
});
private static final ConsumerWrapper> sSink = wrapConsumer(new Consumer() {
public void accept(final Object in) {}
});
/**
* Avoid direct instantiation.
*/
protected Functions() {
}
/**
* Returns a bi-consumer wrapper just discarding the passed inputs.
* The returned object will support concatenation and comparison.
*
* @param the first input data type.
* @param the second input data type.
* @return the bi-consumer wrapper.
*/
@NotNull
@SuppressWarnings("unchecked")
public static BiConsumerWrapper biSink() {
return (BiConsumerWrapper) sBiSink;
}
/**
* Returns a functional routine builder.
*
* @return the routine builder instance.
*/
@NotNull
public static FunctionalRoutineBuilder builder() {
return new DefaultFunctionalRoutineBuilder();
}
/**
* Returns a supplier wrapper always returning the same result.
* The returned object will support concatenation and comparison.
*
* @param result the result.
* @param the output data type.
* @return the supplier wrapper.
*/
@NotNull
public static SupplierWrapper constant(final OUT result) {
return wrapSupplier(new Supplier() {
public OUT get() {
return result;
}
});
}
/**
* Builds and returns a new command invocation based on the specified consumer instance.
* In order to prevent undesired leaks, the class of the specified consumer must have a static
* context.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param consumer the consumer instance.
* @param the output data type.
* @return the command invocation.
*/
@NotNull
public static CommandInvocation consumerCommand(
@NotNull final Consumer super ResultChannel> consumer) {
return new ConsumerCommandInvocation(wrapConsumer(consumer));
}
/**
* Builds and returns a new invocation factory based on the specified bi-consumer instance.
* In order to prevent undesired leaks, the class of the specified bi-consumer must have a
* static context.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param consumer the bi-consumer instance.
* @param the input data type.
* @param the output data type.
* @return the invocation factory.
*/
@NotNull
public static InvocationFactory consumerFactory(
@NotNull final BiConsumer super List extends IN>, ? super ResultChannel>
consumer) {
return new ConsumerInvocationFactory(wrapBiConsumer(consumer));
}
/**
* Builds and returns a new filter invocation based on the specified bi-consumer instance.
* In order to prevent undesired leaks, the class of the specified bi-consumer must have a
* static context.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param consumer the bi-consumer instance.
* @param the input data type.
* @param the output data type.
* @return the filter invocation.
*/
@NotNull
public static FilterInvocation consumerFilter(
@NotNull final BiConsumer super IN, ? super ResultChannel> consumer) {
return new ConsumerFilterInvocation(wrapBiConsumer(consumer));
}
/**
* Returns a bi-function wrapper just returning the first passed argument.
* The returned object will support concatenation and comparison.
*
* @param the first input data type.
* @param the second input data type.
* @return the bi-function wrapper.
*/
@NotNull
@SuppressWarnings("unchecked")
public static BiFunctionWrapper first() {
return (BiFunctionWrapper) sFirst;
}
/**
* Builds and returns a new invocation factory based on the specified function instance.
* In order to prevent undesired leaks, the class of the specified function must have a static
* context.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param function the function instance.
* @param the input data type.
* @param the output data type.
* @return the invocation factory.
*/
@NotNull
public static InvocationFactory functionFactory(
@NotNull final Function super List extends IN>, OUT> function) {
return new FunctionInvocationFactory(wrapFunction(function));
}
/**
* Builds and returns a new filter invocation based on the specified function instance.
* In order to prevent undesired leaks, the class of the specified function must have a static
* context.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param function the function instance.
* @param the input data type.
* @param the output data type.
* @return the filter invocation.
*/
@NotNull
public static FilterInvocation functionFilter(
@NotNull final Function super IN, OUT> function) {
return new FunctionFilterInvocation(wrapFunction(function));
}
/**
* Returns the identity function wrapper.
* The returned object will support concatenation and comparison.
*
* @param the input data type.
* @return the function wrapper.
*/
@NotNull
@SuppressWarnings("unchecked")
public static FunctionWrapper identity() {
return (FunctionWrapper) sIdentity;
}
/**
* Returns a predicate wrapper returning true when the passed argument is null.
* The returned object will support concatenation and comparison.
*
* @param the input data type.
* @return the predicate wrapper.
*/
@NotNull
@SuppressWarnings("unchecked")
public static PredicateWrapper isNull() {
return (PredicateWrapper) sIsNull;
}
/**
* Returns a predicate wrapper always returning the false.
* The returned object will support concatenation and comparison.
*
* @param the input data type.
* @return the predicate wrapper.
*/
@NotNull
@SuppressWarnings("unchecked")
public static PredicateWrapper negative() {
return (PredicateWrapper) sNegative;
}
/**
* Returns a predicate wrapper returning true when the passed argument is not null.
* The returned object will support concatenation and comparison.
*
* @param the input data type.
* @return the predicate wrapper.
*/
@NotNull
@SuppressWarnings("unchecked")
public static PredicateWrapper notNull() {
return (PredicateWrapper) sNotNull;
}
/**
* Returns an output consumer builder employing the specified consumer function to handle the
* invocation completion.
*
* @param consumer the consumer function.
* @return the builder instance.
*/
@NotNull
public static OutputConsumerBuilder onComplete(@NotNull final Consumer consumer) {
return new OutputConsumerBuilder(wrapConsumer(consumer),
Functions.sink(),
Functions.sink());
}
/**
* Returns an output consumer builder employing the specified consumer function to handle the
* invocation errors.
*
* @param consumer the consumer function.
* @return the builder instance.
*/
@NotNull
public static OutputConsumerBuilder onError(
@NotNull final Consumer consumer) {
return new OutputConsumerBuilder(Functions.sink(), wrapConsumer(consumer),
Functions.sink());
}
/**
* Returns an output consumer builder employing the specified consumer function to handle the
* invocation outputs.
*
* @param consumer the consumer function.
* @param the output data type.
* @return the builder instance.
*/
@NotNull
public static OutputConsumerBuilder onOutput(@NotNull final Consumer consumer) {
return new OutputConsumerBuilder(Functions.sink(),
Functions.sink(),
wrapConsumer(consumer));
}
/**
* Returns a predicate wrapper always returning the true.
* The returned object will support concatenation and comparison.
*
* @param the input data type.
* @return the predicate wrapper.
*/
@NotNull
@SuppressWarnings("unchecked")
public static PredicateWrapper positive() {
return (PredicateWrapper) sPositive;
}
/**
* Builds and returns a new filter invocation based on the specified predicate instance.
* Only the inputs which satisfies the predicate will be passed on, while the others will be
* filtered out.
* In order to prevent undesired leaks, the class of the specified predicate must have a static
* context.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param predicate the predicate instance.
* @param the input data type.
* @return the invocation factory.
*/
@NotNull
public static FilterInvocation predicateFilter(
@NotNull final Predicate super IN> predicate) {
return new PredicateFilterInvocation(wrapPredicate(predicate));
}
/**
* Returns a bi-function wrapper just returning the second passed argument.
* The returned object will support concatenation and comparison.
*
* @param the first input data type.
* @param the second input data type.
* @return the bi-function wrapper.
*/
@NotNull
@SuppressWarnings("unchecked")
public static BiFunctionWrapper second() {
return (BiFunctionWrapper) sSecond;
}
/**
* Returns a consumer wrapper just discarding the passed inputs.
* The returned object will support concatenation and comparison.
*
* @param the input data type.
* @return the consumer wrapper.
*/
@NotNull
@SuppressWarnings("unchecked")
public static ConsumerWrapper sink() {
return (ConsumerWrapper) sSink;
}
/**
* Builds and returns a new command invocation based on the specified supplier instance.
* In order to prevent undesired leaks, the class of the specified supplier must have a static
* context.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param supplier the supplier instance.
* @param the output data type.
* @return the command invocation.
*/
@NotNull
public static CommandInvocation supplierCommand(
@NotNull final Supplier supplier) {
return new SupplierCommandInvocation(wrapSupplier(supplier));
}
/**
* Builds and returns a new invocation factory based on the specified supplier instance.
* In order to prevent undesired leaks, the class of the specified supplier must have a static
* context.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param supplier the supplier instance.
* @param the input data type.
* @param the output data type.
* @return the invocation factory.
*/
@NotNull
public static InvocationFactory supplierFactory(
@NotNull final Supplier extends Invocation> supplier) {
return new SupplierInvocationFactory(wrapSupplier(supplier));
}
/**
* Wraps the specified bi-consumer instance so to provide additional features.
* The returned object will support concatenation and comparison.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param consumer the bi-consumer instance.
* @param the first input data type.
* @param the second input data type.
* @return the wrapped bi-consumer.
*/
@NotNull
public static BiConsumerWrapper wrapBiConsumer(
@NotNull final BiConsumer consumer) {
if (consumer.getClass() == BiConsumerWrapper.class) {
return (BiConsumerWrapper) consumer;
}
return new BiConsumerWrapper(
Collections.>singletonList(consumer));
}
/**
* Wraps the specified bi-function instance so to provide additional features.
* The returned object will support concatenation and comparison.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param function the bi-function instance.
* @param the first input data type.
* @param the second input data type.
* @param the output data type.
* @return the wrapped bi-function.
*/
@NotNull
public static BiFunctionWrapper wrapBiFunction(
@NotNull final BiFunction function) {
if (function.getClass() == BiFunctionWrapper.class) {
return (BiFunctionWrapper) function;
}
return new BiFunctionWrapper(function,
wrapFunction(Functions.identity()));
}
/**
* Wraps the specified consumer instance so to provide additional features.
* The returned object will support concatenation and comparison.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param consumer the consumer instance.
* @param the input data type.
* @return the wrapped consumer.
*/
@NotNull
public static ConsumerWrapper wrapConsumer(@NotNull final Consumer consumer) {
if (consumer.getClass() == ConsumerWrapper.class) {
return (ConsumerWrapper) consumer;
}
return new ConsumerWrapper(Collections.>singletonList(consumer));
}
/**
* Wraps the specified function instance so to provide additional features.
* The returned object will support concatenation and comparison.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param function the function instance.
* @param the input data type.
* @param the output data type.
* @return the wrapped function.
*/
@NotNull
public static FunctionWrapper wrapFunction(
@NotNull final Function function) {
if (function.getClass() == FunctionWrapper.class) {
return (FunctionWrapper) function;
}
return new FunctionWrapper(Collections.>singletonList(function));
}
/**
* Wraps the specified predicate instance so to provide additional features.
* The returned object will support concatenation and comparison.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param predicate the predicate instance.
* @param the input data type.
* @return the wrapped predicate.
*/
@NotNull
public static PredicateWrapper wrapPredicate(@NotNull final Predicate predicate) {
if (predicate.getClass() == PredicateWrapper.class) {
return (PredicateWrapper) predicate;
}
return new PredicateWrapper(predicate,
Collections.>singletonList(predicate));
}
/**
* Wraps the specified supplier instance so to provide additional features.
* The returned object will support concatenation and comparison.
*
* Note that the passed object is expected to behave like a function, that is, it must not
* retain a mutable internal state.
* Note also that any external object used inside the function must be synchronized in order to
* avoid concurrency issues.
*
* @param supplier the supplier instance.
* @param the output data type.
* @return the wrapped supplier.
*/
@NotNull
public static SupplierWrapper wrapSupplier(@NotNull final Supplier supplier) {
if (supplier.getClass() == SupplierWrapper.class) {
return (SupplierWrapper) supplier;
}
return new SupplierWrapper(supplier, Functions.identity());
}
/**
* Command invocation based on a consumer instance.
*
* @param the output data type.
*/
private static class ConsumerCommandInvocation extends CommandInvocation {
private final ConsumerWrapper super ResultChannel> mConsumer;
/**
* Constructor.
*
* @param consumer the consumer instance.
*/
public ConsumerCommandInvocation(
@NotNull final ConsumerWrapper super ResultChannel> consumer) {
if (!consumer.hasStaticContext()) {
throw new IllegalArgumentException(
"the consumer class must have a static context: " + consumer.getClass());
}
mConsumer = consumer;
}
@Override
public int hashCode() {
return mConsumer.hashCode();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof ConsumerCommandInvocation)) {
return false;
}
final ConsumerCommandInvocation> that = (ConsumerCommandInvocation>) o;
return mConsumer.equals(that.mConsumer);
}
public void onResult(@NotNull final ResultChannel result) {
mConsumer.accept(result);
}
}
/**
* Filter invocation based on a bi-consumer instance.
*
* @param the input data type.
* @param the output data type.
*/
private static class ConsumerFilterInvocation extends FilterInvocation {
private final BiConsumerWrapper super IN, ? super ResultChannel> mConsumer;
/**
* Constructor.
*
* @param consumer the consumer instance.
*/
private ConsumerFilterInvocation(
@NotNull final BiConsumerWrapper super IN, ? super ResultChannel> consumer) {
if (!consumer.hasStaticContext()) {
throw new IllegalArgumentException(
"the bi-consumer class must have a static context: " + consumer.getClass());
}
mConsumer = consumer;
}
public void onInput(final IN input, @NotNull final ResultChannel result) {
mConsumer.accept(input, result);
}
@Override
public int hashCode() {
return mConsumer.hashCode();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof ConsumerFilterInvocation)) {
return false;
}
final ConsumerFilterInvocation, ?> that = (ConsumerFilterInvocation, ?>) o;
return mConsumer.equals(that.mConsumer);
}
}
/**
* Factory of function invocations based on a bi-consumer instance.
*
* @param the input data type.
* @param the output data type.
*/
private static class ConsumerInvocationFactory extends InvocationFactory {
private final BiConsumerWrapper super List extends IN>, ? super ResultChannel>
mConsumer;
private final FunctionInvocation mInvocation;
/**
* Constructor.
*
* @param consumer the consumer instance.
*/
private ConsumerInvocationFactory(
@NotNull final BiConsumerWrapper super List extends IN>, ? super
ResultChannel> consumer) {
if (!consumer.hasStaticContext()) {
throw new IllegalArgumentException(
"the bi-consumer class must have a static context: " + consumer.getClass());
}
mConsumer = consumer;
mInvocation = new FunctionInvocation() {
@Override
protected void onCall(@NotNull final List extends IN> inputs,
@NotNull final ResultChannel result) {
consumer.accept(inputs, result);
}
};
}
@NotNull
@Override
public Invocation newInvocation() {
return mInvocation;
}
@Override
public int hashCode() {
return mConsumer.hashCode();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof ConsumerInvocationFactory)) {
return false;
}
final ConsumerInvocationFactory, ?> that = (ConsumerInvocationFactory, ?>) o;
return mConsumer.equals(that.mConsumer);
}
}
/**
* Filter invocation based on a function instance.
*
* @param the input data type.
* @param the output data type.
*/
private static class FunctionFilterInvocation extends FilterInvocation {
private final FunctionWrapper super IN, OUT> mFunction;
/**
* Constructor.
*
* @param function the function instance.
*/
private FunctionFilterInvocation(@NotNull final FunctionWrapper super IN, OUT> function) {
if (!function.hasStaticContext()) {
throw new IllegalArgumentException(
"the function class must have a static context: " + function.getClass());
}
mFunction = function;
}
@Override
public int hashCode() {
return mFunction.hashCode();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof FunctionFilterInvocation)) {
return false;
}
final FunctionFilterInvocation, ?> that = (FunctionFilterInvocation, ?>) o;
return mFunction.equals(that.mFunction);
}
public void onInput(final IN input, @NotNull final ResultChannel result) {
result.pass(mFunction.apply(input));
}
}
/**
* Factory of function invocations based on a function instance.
*
* @param the input data type.
* @param the output data type.
*/
private static class FunctionInvocationFactory extends InvocationFactory {
private final FunctionWrapper super List extends IN>, OUT> mFunction;
private final FunctionInvocation mInvocation;
/**
* Constructor.
*
* @param function the function instance.
*/
private FunctionInvocationFactory(
@NotNull final FunctionWrapper super List extends IN>, OUT> function) {
if (!function.hasStaticContext()) {
throw new IllegalArgumentException(
"the function class must have a static context: " + function.getClass());
}
mFunction = function;
mInvocation = new FunctionInvocation() {
@Override
protected void onCall(@NotNull final List extends IN> inputs,
@NotNull final ResultChannel result) {
result.pass(function.apply(inputs));
}
};
}
@NotNull
@Override
public Invocation newInvocation() {
return mInvocation;
}
@Override
public int hashCode() {
return mFunction.hashCode();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof FunctionInvocationFactory)) {
return false;
}
final FunctionInvocationFactory, ?> that = (FunctionInvocationFactory, ?>) o;
return mFunction.equals(that.mFunction);
}
}
/**
* Filter invocation based on a predicate instance.
*
* @param the input data type.
*/
private static class PredicateFilterInvocation extends FilterInvocation {
private final PredicateWrapper super IN> mPredicate;
/**
* Constructor.
*
* @param predicate the predicate instance.
*/
private PredicateFilterInvocation(@NotNull final PredicateWrapper super IN> predicate) {
if (!predicate.hasStaticContext()) {
throw new IllegalArgumentException(
"the predicate class must have a static context: " + predicate.getClass());
}
mPredicate = predicate;
}
@Override
public int hashCode() {
return mPredicate.hashCode();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof PredicateFilterInvocation)) {
return false;
}
final PredicateFilterInvocation> that = (PredicateFilterInvocation>) o;
return mPredicate.equals(that.mPredicate);
}
public void onInput(final IN input, @NotNull final ResultChannel result) {
if (mPredicate.test(input)) {
result.pass(input);
}
}
}
/**
* Command invocation based on a supplier instance.
*
* @param the output data type.
*/
private static class SupplierCommandInvocation extends CommandInvocation {
private final SupplierWrapper mSupplier;
/**
* Constructor.
*
* @param supplier the supplier instance.
*/
public SupplierCommandInvocation(@NotNull final SupplierWrapper supplier) {
if (!supplier.hasStaticContext()) {
throw new IllegalArgumentException(
"the supplier class must have a static context: " + supplier.getClass());
}
mSupplier = supplier;
}
@Override
public int hashCode() {
return mSupplier.hashCode();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SupplierCommandInvocation)) {
return false;
}
final SupplierCommandInvocation> that = (SupplierCommandInvocation>) o;
return mSupplier.equals(that.mSupplier);
}
public void onResult(@NotNull final ResultChannel result) {
result.pass(mSupplier.get());
}
}
/**
* Implementation of an invocation factory based on a supplier function.
*
* @param the input data type.
* @param the output data type.
*/
private static class SupplierInvocationFactory extends InvocationFactory {
private final SupplierWrapper extends Invocation> mSupplier;
/**
* Constructor.
*
* @param supplier the supplier function.
*/
private SupplierInvocationFactory(
@NotNull final SupplierWrapper extends Invocation> supplier) {
if (!supplier.hasStaticContext()) {
throw new IllegalArgumentException(
"the supplier class must have a static context: " + supplier.getClass());
}
mSupplier = supplier;
}
@NotNull
@Override
public Invocation newInvocation() {
return mSupplier.get();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SupplierInvocationFactory)) {
return false;
}
final SupplierInvocationFactory, ?> that = (SupplierInvocationFactory, ?>) o;
return mSupplier.equals(that.mSupplier);
}
@Override
public int hashCode() {
return mSupplier.hashCode();
}
}
}