package com.github.davidmoten.rx; import java.util.Comparator; import java.util.concurrent.Callable; import rx.Observable; import rx.functions.Func0; import rx.functions.Func1; import rx.functions.Func2; public final class Functions { private Functions() { // prevent instantiation } public static <T> Func1<T, T> identity() { return new Func1<T, T>() { @Override public T call(T t) { return t; } }; } public static <T> Func1<T, Boolean> alwaysTrue() { return new Func1<T, Boolean>() { @Override public Boolean call(T t) { return true; } }; } public static <T> Func1<T, Boolean> alwaysFalse() { return new Func1<T, Boolean>() { @Override public Boolean call(T t) { return false; } }; } public static <T, R> Func1<T, R> constant(final R r) { return new Func1<T, R>() { @Override public R call(T t) { return r; } }; } public static <T> Func0<T> constant0(final T t) { return new Func0<T>() { @Override public T call() { return t; } }; } public static <T> Func1<T, Boolean> not(final Func1<T, Boolean> f) { return new Func1<T, Boolean>() { @Override public Boolean call(T t) { return !f.call(t); } }; } public static <T> Func1<T, Observable<T>> just() { return new Func1<T, Observable<T>>() { @Override public Observable<T> call(T t) { return Observable.just(t); } }; } /** * Returns a Func2 that adds numbers. Useful for Observable.reduce but not * particularly performant as it does instanceOf checks. * * @param <T> * generic type of Number being added * @return Func2 that adds numbers */ public static <T extends Number> Func2<T, T, T> add() { return new Func2<T, T, T>() { @SuppressWarnings("unchecked") @Override public T call(T a, T b) { if (a instanceof Integer) return (T) (Number) (a.intValue() + b.intValue()); else if (a instanceof Long) return (T) (Number) (a.longValue() + b.longValue()); else if (a instanceof Double) return (T) (Number) (a.doubleValue() + b.doubleValue()); else if (a instanceof Float) return (T) (Number) (a.floatValue() + b.floatValue()); else if (a instanceof Byte) return (T) (Number) (a.byteValue() + b.byteValue()); else if (a instanceof Short) return (T) (Number) (a.shortValue() + b.shortValue()); else throw new RuntimeException("not implemented"); } }; } public static <T extends Number> Func2<Statistics, T, Statistics> collectStats() { return new Func2<Statistics, T, Statistics>() { @Override public Statistics call(Statistics s, T t) { return s.add(t); } }; } public static <T> Func2<T, T, Integer> toFunc2(final Comparator<? super T> comparator) { return new Func2<T, T, Integer>() { @Override public Integer call(T t1, T t2) { return comparator.compare(t1, t2); } }; } public static <T> Comparator<T> toComparator(final Func2<? super T, ? super T, Integer> f) { return new Comparator<T>() { @Override public int compare(T a, T b) { return f.call(a, b); } }; } public static <T, R> Func2<T, R, Boolean> alwaysTrue2() { return new Func2<T, R, Boolean>() { @Override public Boolean call(T t1, R t2) { return true; } }; } public static <T, R> Func2<T, R, Boolean> alwaysFalse2() { return new Func2<T, R, Boolean>() { @Override public Boolean call(T t1, R t2) { return false; } }; } public static <T> Func1<T, Boolean> isNull() { return new Func1<T, Boolean>() { @Override public Boolean call(T t) { return t == null; } }; } public static <T> Func1<T, Boolean> isNotNull() { return new Func1<T, Boolean>() { @Override public Boolean call(T t) { return t != null; } }; } public static <T> Func0<T> toFunc0(final Callable<T> f) { return new Func0<T>() { @Override public T call() { try { return f.call(); } catch (Exception e) { throw new RuntimeException(e); } } }; } public static <T, R, S> Func2<T, R, S> throwing2() { return new Func2<T, R, S>() { @Override public S call(T t, R r) { throw new ThrowingException(); } }; } public static <T, R> Func1<T, R> throwing() { return new Func1<T, R>() { @Override public R call(T t) { throw new ThrowingException(); } }; } public static final class ThrowingException extends RuntimeException { private static final long serialVersionUID = 930909878278758496L; } }