
net.diversionmc.error.Functionals Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of result Show documentation
Show all versions of result Show documentation
Diversion Network Result type.
package net.diversionmc.error;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.function.*;
import java.util.stream.Collector;
import java.util.stream.Stream;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
import static net.diversionmc.error.Result.tryGet;
/**
* Utils for {@link Result}, {@link Success}, {@link Optional}, {@link Stream} types.
*/
@SuppressWarnings("unused")
public class Functionals {
public static void noop() {
}
//
// Optional, Stream
//
/**
* @return {@link Optional#of(Object)}
*/
public static Optional some(T t) {
return Optional.of(t);
}
/**
* @return {@link Optional#ofNullable(Object)}
*/
public static Optional optional(T t) {
return Optional.ofNullable(t);
}
/**
* @return {@link Stream#ofNullable(Object)}
*/
@SafeVarargs
public static Stream stream(T... t) {
return Stream.of(t)
.filter(Objects::nonNull);
}
/**
* @return {@link Optional#empty()}
*/
public static Optional none() {
return Optional.empty();
}
/**
* Convert boolean to optional.
*
* @param test Boolean to convert.
* @param ifTrue Object to wrap on true test value.
* @param Optional type.
* @return Optional wrapping value if check has passed.
*/
public static Optional optional(boolean test, Supplier ifTrue) {
return test ? some(ifTrue.get()) : none();
}
/**
* Convert boolean to optional.
*
* @param test Boolean to convert.
* @param ifTrue Object to wrap on true test value.
* @param Optional type.
* @return Optional wrapping value if check has passed.
*/
public static Optional optional(boolean test, T ifTrue) {
return test ? some(ifTrue) : none();
}
//
// Reflective Casts
//
/**
* Try to dynamically cast an object to a type.
* Used for functional style castings in streams and such.
*
* @param obj Object to cast.
* @param Type to cast to.
* @return Casted type or empty optional.
*/
public static Optional cast(Object obj, Class c) {
return tryGet(
ClassCastException.class,
TryS.of(applyF2(Class::cast, c, obj)))
.mapOk(Functionals::optional)
.ok()
.flatMap(identity());
}
public static Function> cast(Class c) {
return applyF2F(Functionals::cast, c);
}
public static Function> castStream(Class c) {
return Functionals
.cast(c)
.andThen(Optional::stream);
}
//
// Entry
//
public static Predicate byKey(T key) {
return byKey(
key,
identity(),
Objects::equals);
}
public static Predicate byKey(K key, Function keyExtractor) {
return byKey(
key,
keyExtractor,
Objects::equals);
}
public static Predicate byKey(K key, BiPredicate keyEquality) {
return byKey(
key,
identity(),
keyEquality);
}
public static Predicate byKey(K1 key,
Function keyExtractor,
BiPredicate keyEquality) {
return repeatP(mapP(
keyEquality,
ignoreS(applyS(key)),
keyExtractor));
}
public static Predicate> byEntryKey(Predicate keyCheck) {
return mapP(
keyCheck,
Entry::getKey);
}
public static Predicate> byEntryValue(Predicate valueCheck) {
return mapP(
valueCheck,
Entry::getValue);
}
public static Predicate> byEntry(BiPredicate entryCheck) {
return repeatP(mapP(
entryCheck,
Entry::getKey,
Entry::getValue));
}
public static Collector, ?, Map> toEntryMap() {
return toMap(
Entry::getKey,
Entry::getValue);
}
public static > Collector, ?, M> toEntryMap(Supplier map) {
return toMap(
Entry::getKey,
Entry::getValue,
Functionals.ignoreF()::apply,
map);
}
//
// Lambda Conversion (keeping the parameter count)
//
// BiF(A, B)->bool -> BiP(A, B)
// F(T)->bool -> P(T)
public static BiPredicate test2(BiFunction f) {
return f::apply;
}
public static Predicate test(Function f) {
return f::apply;
}
// BiP -> BiP
// P -> P
// P,P -> BiP
public static BiPredicate not(BiPredicate f) {
return f.negate();
}
public static Predicate not(Predicate f) {
return f.negate();
}
public static BiPredicate and(Predicate fa, Predicate fb) {
return mapP(
Boolean::logicalAnd,
fa::test,
fb::test);
}
public static BiPredicate or(Predicate fa, Predicate fb) {
return mapP(
Boolean::logicalOr,
fa::test,
fb::test);
}
// Other
public static T map(T t, Predicate check, Function ifTrue) {
return map(t, check, ifTrue, identity());
}
public static T map(T t, Predicate check,
Function ifTrue,
Function ifFalse) {
return (check.test(t) ? ifTrue : ifFalse).apply(t);
}
// Flip
// BiF(A, B)->BiF(B, A)
// BiP(A, B)->BiP(B, A)
// BiC(A, B)->BiC(B, A)
public static BiFunction flipF(BiFunction f) {
return (b, a) -> f.apply(a, b);
}
public static BiPredicate flipP(BiPredicate f) {
return (b, a) -> f.test(a, b);
}
public static BiConsumer flipC(BiConsumer f) {
return (b, a) -> f.accept(a, b);
}
//
// Partial Application (lower the parameter count by supplying them)
//
// Function
// BiF(A, B)->R -> F(B)->R
// BiF(A, B)->R -> F(A)->R
// BiF(A, B)->R -> S()->R
// F(T)->R -> S()->R
public static Function applyF2(BiFunction f, A a) {
return b -> f.apply(a, b);
}
public static Function applyF2F(BiFunction f, B b) {
return applyF2(flipF(f), b);
}
public static Supplier applyF2(BiFunction f, A a, B b) {
return () -> f.apply(a, b);
}
public static Supplier applyF(Function f, T t) {
return () -> f.apply(t);
}
// BiF(S()->A, B)->R -> F(B)->R
// BiF(A, S()->B)->R -> F(A)->R
// BiF(S()->A, S()->B)->R -> S()->R
// F(S()->T)->R -> S()->R
public static Function applyF2S(BiFunction f, Supplier a) {
return b -> f.apply(a.get(), b);
}
public static Function applyF2SF(BiFunction f, Supplier b) {
return applyF2S(flipF(f), b);
}
public static Supplier applyF2S(BiFunction f, Supplier a, Supplier b) {
return () -> f.apply(a.get(), b.get());
}
public static Supplier applyFS(Function f, Supplier t) {
return () -> f.apply(t.get());
}
// Predicate
// BiP(A, B) -> P(B)
// BiF(A, B) -> P(A)
public static Predicate applyP2(BiPredicate f, A a) {
return b -> f.test(a, b);
}
public static Predicate applyP2F(BiPredicate f, B b) {
return applyP2(flipP(f), b);
}
// BiP(S()->A, B) -> P(B)
// BiF(A, S()->B) -> P(A)
public static Predicate applyP2S(BiPredicate f, Supplier a) {
return b -> f.test(a.get(), b);
}
public static Predicate applyP2SF(BiPredicate f, Supplier b) {
return applyP2S(flipP(f), b);
}
// Consumer
// BiC(A, B) -> C(A)
// BiC(A, B) -> C(B)
// BiC(A, B) -> R()
// C(T) -> R()
public static Consumer applyC2(BiConsumer f, A a) {
return b -> f.accept(a, b);
}
public static Consumer applyC2F(BiConsumer f, B b) {
return applyC2(flipC(f), b);
}
public static Runnable applyC2(BiConsumer f, A a, B b) {
return () -> f.accept(a, b);
}
public static Runnable applyC(Consumer f, T t) {
return () -> f.accept(t);
}
// BiC(S()->A, B) -> C(A)
// BiC(A, S()->B) -> C(B)
// BiC(S()->A, S()->B) -> R()
// C(S()->T) -> R()
public static Consumer applyC2S(BiConsumer f, Supplier a) {
return b -> f.accept(a.get(), b);
}
public static Consumer applyC2SF(BiConsumer f, Supplier b) {
return applyC2S(flipC(f), b);
}
public static Runnable applyC2S(BiConsumer f, Supplier a, Supplier b) {
return () -> f.accept(a.get(), b.get());
}
public static Runnable applyCS(Consumer f, Supplier t) {
return () -> f.accept(t.get());
}
// Supplier
// T -> S()->T
public static Supplier applyS(T t) {
return () -> t;
}
//
// Parameter Ignorance (raise the parameter count by ignoring them)
//
// Function
// F(A)->R -> BiF(A, B)->R
public static BiFunction ignoreF(Function f) {
return (a, b) -> f.apply(a);
}
public static BiFunction ignoreF() {
return ignoreF(identity());
}
// Predicate
// P(A) -> BiP(A, B)
public static BiPredicate ignoreP(Predicate f) {
return (a, b) -> f.test(a);
}
// Consumer
// C(A) -> BiC(A, B)
public static BiConsumer ignoreC(Consumer f) {
return (a, b) -> f.accept(a);
}
public static BiConsumer ignoreC() {
return ignoreC(ignoreR());
}
// Supplier
// S()->R -> BiF(A, B)->R
// S()->R -> F(T)->R
public static BiFunction ignoreS2(Supplier f) {
return (a, b) -> f.get();
}
public static Function ignoreS(Supplier f) {
return t -> f.get();
}
// Runnable
// R() -> BiC(A, B)
// R() -> C(T)
public static BiConsumer ignoreR2(Runnable f) {
return (a, b) -> f.run();
}
public static BiConsumer ignoreR2() {
return ignoreR2(Functionals::noop);
}
public static Consumer ignoreR(Runnable f) {
return t -> f.run();
}
public static Consumer ignoreR() {
return ignoreR(Functionals::noop);
}
//
// Parameter Repeating (lower the parameter count by repeating them)
//
// Function
public static Function repeatF(BiFunction f) {
return t -> f.apply(t, t);
}
// Predicate
public static Predicate repeatP(BiPredicate f) {
return t -> f.test(t, t);
}
// Consumer
public static Consumer repeatC(BiConsumer f) {
return t -> f.accept(t, t);
}
//
// Mapping (keeping the parameter count, but converting input types)
//
// Function
public static BiFunction mapF(BiFunction f,
Function na,
Function mb) {
return (n, m) -> f.apply(na.apply(n), mb.apply(m));
}
public static Function mapF(Function f,
Function na) {
return f.compose(na);
}
// Predicate
public static BiPredicate mapP(BiPredicate f,
Function na,
Function mb) {
return (n, m) -> f.test(na.apply(n), mb.apply(m));
}
public static Predicate mapP(Predicate f,
Function na) {
return n -> f.test(na.apply(n));
}
// Consumer
public static BiConsumer mapC(BiConsumer f,
Function na,
Function mb) {
return (n, m) -> f.accept(na.apply(n), mb.apply(m));
}
public static Consumer mapC(Consumer f,
Function na) {
return n -> f.accept(na.apply(n));
}
// Supplier
public static Supplier mapS(Supplier f,
Function na) {
return applyFS(na, f);
}
//
// Higher Order Partial Application
//
// Function
public static Function, R> flatApplyF(T t) {
return applyF2F(Function::apply, t);
}
// Predicate
public static Predicate> flatApplyP(T t) {
return applyP2F(Predicate::test, t);
}
// Consumer
public static Consumer> flatApplyC(T t) {
return applyC2F(Consumer::accept, t);
}
// Supplier
public static Supplier> flatApplyS(T t) {
return applyS(applyS(t));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy