/* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/licenses/publicdomain */ package extra166y; import jsr166y.*; import static extra166y.Ops.*; import java.util.*; /** * A collection of static factory methods providing commonly useful * implementations of operations. */ public class CommonOps { private CommonOps() {} // disable construction /** * Returns a Comparator for Comparable objects */ public static > Comparator naturalComparator(Class type) { return new Comparator() { public int compare(T a, T b) { return a.compareTo(b); } }; } /** * Returns a reducer returning the maximum of two Comparable * elements, treating null as less than any non-null element. */ public static > Reducer naturalMaxReducer(Class type) { return new Reducer() { public T op(T a, T b) { return (a != null && (b == null || a.compareTo(b) >= 0))? a : b; } }; } /** * Returns a reducer returning the minimum of two Comparable * elements, treating null as greater than any non-null element. */ public static > Reducer naturalMinReducer(Class type) { return new Reducer() { public T op(T a, T b) { return (a != null && (b == null || a.compareTo(b) <= 0))? a : b; } }; } /** * Returns a reducer returning the maximum of two elements, using * the given comparator, and treating null as less than any * non-null element. */ public static Reducer maxReducer (final Comparator comparator) { return new Reducer() { public T op(T a, T b) { return (a != null && (b == null || comparator.compare(a, b) >= 0))? a : b; } }; } /** * Returns a reducer returning the minimum of two elements, using * the given comparator, and treating null as greater than any * non-null element. */ public static Reducer minReducer (final Comparator comparator) { return new Reducer() { public T op(T a, T b) { return (a != null && (b == null || comparator.compare(a, b) <= 0))? a : b; } }; } /** * Returns a Comparator that casts its arguments as Comparable on * each comparison, throwing ClassCastException on failure. */ public static Comparator castedComparator() { return (Comparator)(RawComparator.cmp); } static final class RawComparator implements Comparator { static final RawComparator cmp = new RawComparator(); public int compare(Object a, Object b) { return ((Comparable)a).compareTo((Comparable)b); } } /** * Returns a reducer returning maximum of two values, or * null if both arguments are null, and that casts * its arguments as Comparable on each comparison, throwing * ClassCastException on failure. */ public static Reducer castedMaxReducer() { return (Reducer)RawMaxReducer.max; } static final class RawMaxReducer implements Reducer { static final RawMaxReducer max = new RawMaxReducer(); public Object op(Object a, Object b) { return (a != null && (b == null || ((Comparable)a).compareTo((Comparable)b) >= 0))? a : b; } } /** * Returns a reducer returning minimum of two values, or * null if both arguments are null, and that casts * its arguments as Comparable on each comparison, throwing * ClassCastException on failure. */ public static Reducer castedMinReducer() { return (Reducer)RawMinReducer.min; } static final class RawMinReducer implements Reducer { static final RawMinReducer min = new RawMinReducer(); public Object op(Object a, Object b) { return (a != null && (b == null || ((Comparable)a).compareTo((Comparable)b) <= 0))? a : b; } } /** * Returns a comparator for doubles relying on natural ordering */ public static DoubleComparator naturalDoubleComparator() { return NaturalDoubleComparator.comparator; } static final class NaturalDoubleComparator implements DoubleComparator { static final NaturalDoubleComparator comparator = new NaturalDoubleComparator(); public int compare(double a, double b) { return Double.compare(a, b); } } /** * Returns a reducer returning the maximum of two double elements, * using natural comparator */ public static DoubleReducer naturalDoubleMaxReducer() { return NaturalDoubleMaxReducer.max; } static final class NaturalDoubleMaxReducer implements DoubleReducer { public static final NaturalDoubleMaxReducer max = new NaturalDoubleMaxReducer(); public double op(double a, double b) { return Math.max(a, b); } } /** * Returns a reducer returning the minimum of two double elements, * using natural comparator */ public static DoubleReducer naturalDoubleMinReducer() { return NaturalDoubleMinReducer.min; } static final class NaturalDoubleMinReducer implements DoubleReducer { public static final NaturalDoubleMinReducer min = new NaturalDoubleMinReducer(); public double op(double a, double b) { return Math.min(a, b); } } /** * Returns a reducer returning the maximum of two double elements, * using the given comparator */ public static DoubleReducer doubleMaxReducer (final DoubleComparator comparator) { return new DoubleReducer() { public double op(double a, double b) { return (comparator.compare(a, b) >= 0)? a : b; } }; } /** * Returns a reducer returning the minimum of two double elements, * using the given comparator */ public static DoubleReducer doubleMinReducer (final DoubleComparator comparator) { return new DoubleReducer() { public double op(double a, double b) { return (comparator.compare(a, b) <= 0)? a : b; } }; } /** * Returns a comparator for longs relying on natural ordering */ public static LongComparator naturalLongComparator() { return NaturalLongComparator.comparator; } static final class NaturalLongComparator implements LongComparator { static final NaturalLongComparator comparator = new NaturalLongComparator(); public int compare(long a, long b) { return a < b? -1 : ((a > b)? 1 : 0); } } /** * Returns a reducer returning the maximum of two long elements, * using natural comparator */ public static LongReducer naturalLongMaxReducer() { return NaturalLongMaxReducer.max; } static final class NaturalLongMaxReducer implements LongReducer { public static final NaturalLongMaxReducer max = new NaturalLongMaxReducer(); public long op(long a, long b) { return a >= b? a : b; } } /** * A reducer returning the minimum of two long elements, * using natural comparator */ public static LongReducer naturalLongMinReducer() { return NaturalLongMinReducer.min; } static final class NaturalLongMinReducer implements LongReducer { public static final NaturalLongMinReducer min = new NaturalLongMinReducer(); public long op(long a, long b) { return a <= b? a : b; } } /** * Returns a reducer returning the maximum of two long elements, * using the given comparator */ public static LongReducer longMaxReducer (final LongComparator comparator) { return new LongReducer() { public long op(long a, long b) { return (comparator.compare(a, b) >= 0)? a : b; } }; } /** * Returns a reducer returning the minimum of two long elements, * using the given comparator */ public static LongReducer longMinReducer (final LongComparator comparator) { return new LongReducer() { public long op(long a, long b) { return (comparator.compare(a, b) <= 0)? a : b; } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static Op compoundOp (final Op first, final Op second) { return new Op() { public final V op(T t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static Op compoundOp (final ObjectToDouble first, final DoubleToObject second) { return new Op() { public final V op(T t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static Op compoundOp (final ObjectToLong first, final LongToObject second) { return new Op() { public final V op(T t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static DoubleToObject compoundOp (final DoubleToObject first, final Op second) { return new DoubleToObject() { public final V op(double t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static LongToObject compoundOp (final LongToObject first, final Op second) { return new LongToObject() { public final V op(long t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static ObjectToDouble compoundOp (final Op first, final ObjectToDouble second) { return new ObjectToDouble() { public final double op(T t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static ObjectToLong compoundOp (final Op first, final ObjectToLong second) { return new ObjectToLong() { public final long op(T t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static ObjectToDouble compoundOp (final ObjectToDouble first, final DoubleOp second) { return new ObjectToDouble() { public final double op(T t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static ObjectToLong compoundOp (final ObjectToDouble first, final DoubleToLong second) { return new ObjectToLong() { public final long op(T t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static ObjectToLong compoundOp (final ObjectToLong first, final LongOp second) { return new ObjectToLong() { public final long op(T t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static ObjectToDouble compoundOp (final ObjectToLong first, final LongToDouble second) { return new ObjectToDouble() { public final double op(T t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static DoubleOp compoundOp (final DoubleOp first, final DoubleOp second) { return new DoubleOp() { public final double op(double t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static DoubleToLong compoundOp (final DoubleOp first, final DoubleToLong second) { return new DoubleToLong() { public final long op(double t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static DoubleToLong compoundOp (final DoubleToLong first, final LongOp second) { return new DoubleToLong() { public final long op(double t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static DoubleToObject compoundOp (final DoubleToLong first, final LongToObject second) { return new DoubleToObject() { public final T op(double t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static LongToObject compoundOp (final LongToDouble first, final DoubleToObject second) { return new LongToObject() { public final T op(long t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static LongToDouble compoundOp (final LongOp first, final LongToDouble second) { return new LongToDouble() { public final double op(long t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static LongToDouble compoundOp (final LongToDouble first, final DoubleOp second) { return new LongToDouble() { public final double op(long t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static DoubleToObject compoundOp (final DoubleOp first, final DoubleToObject second) { return new DoubleToObject() { public final T op(double t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static LongToObject compoundOp (final LongOp first, final LongToObject second) { return new LongToObject() { public final T op(long t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static DoubleOp compoundOp (final DoubleToObject first, final ObjectToDouble second) { return new DoubleOp() { public final double op(double t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static LongToDouble compoundOp (final LongToObject first, final ObjectToDouble second) { return new LongToDouble() { public final double op(long t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static DoubleToLong compoundOp (final DoubleToObject first, final ObjectToLong second) { return new DoubleToLong() { public final long op(double t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static LongOp compoundOp (final LongToObject first, final ObjectToLong second) { return new LongOp() { public final long op(long t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static LongOp compoundOp (final LongOp first, final LongOp second) { return new LongOp() { public final long op(long t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static DoubleOp compoundOp (final DoubleToLong first, final LongToDouble second) { return new DoubleOp() { public final double op(double t) { return second.op(first.op(t)); } }; } /** * Returns a composite mapper that applies a second mapper to the results * of applying the first one */ public static LongOp compoundOp (final LongToDouble first, final DoubleToLong second) { return new LongOp() { public final long op(long t) { return second.op(first.op(t)); } }; } /** * Returns a predicate evaluating to the negation of its contained predicate */ public static Predicate notPredicate (final Predicate pred) { return new Predicate() { public final boolean op(T x) { return !pred.op(x); } }; } /** * Returns a predicate evaluating to the negation of its contained predicate */ public static DoublePredicate notPredicate (final DoublePredicate pred) { return new DoublePredicate() { public final boolean op(double x) { return !pred.op(x); } }; } /** * Returns a predicate evaluating to the negation of its contained predicate */ public static LongPredicate notPredicate (final LongPredicate pred) { return new LongPredicate() { public final boolean op(long x) { return !pred.op(x); } }; } /** * Returns a predicate evaluating to the conjunction of its contained predicates */ public static Predicate andPredicate (final Predicate first, final Predicate second) { return new Predicate() { public final boolean op(T x) { return first.op(x) && second.op(x); } }; } /** * Returns a predicate evaluating to the disjunction of its contained predicates */ public static Predicate orPredicate (final Predicate first, final Predicate second) { return new Predicate() { public final boolean op(T x) { return first.op(x) || second.op(x); } }; } /** * Returns a predicate evaluating to the conjunction of its contained predicates */ public static DoublePredicate andPredicate (final DoublePredicate first, final DoublePredicate second) { return new DoublePredicate() { public final boolean op(double x) { return first.op(x) && second.op(x); } }; } /** * Returns a predicate evaluating to the disjunction of its contained predicates */ public static DoublePredicate orPredicate (final DoublePredicate first, final DoublePredicate second) { return new DoublePredicate() { public final boolean op(double x) { return first.op(x) || second.op(x); } }; } /** * Returns a predicate evaluating to the conjunction of its contained predicates */ public static LongPredicate andPredicate (final LongPredicate first, final LongPredicate second) { return new LongPredicate() { public final boolean op(long x) { return first.op(x) && second.op(x); } }; } /** * Returns a predicate evaluating to the disjunction of its contained predicates */ public static LongPredicate orPredicate (final LongPredicate first, final LongPredicate second) { return new LongPredicate() { public final boolean op(long x) { return first.op(x) || second.op(x); } }; } /** * Returns a predicate evaluating to true if its argument is non-null */ public static Predicate isNonNullPredicate() { return IsNonNullPredicate.predicate; } static final class IsNonNullPredicate implements Predicate { static final IsNonNullPredicate predicate = new IsNonNullPredicate(); public final boolean op(Object x) { return x != null; } } /** * Returns a predicate evaluating to true if its argument is null */ public static Predicate isNullPredicate() { return IsNullPredicate.predicate; } static final class IsNullPredicate implements Predicate { static final IsNullPredicate predicate = new IsNullPredicate(); public final boolean op(Object x) { return x != null; } } /** * Returns a predicate evaluating to true if its argument is an instance * of (see {@link Class#isInstance} the given type (class). */ public static Predicate instanceofPredicate(final Class type) { return new Predicate() { public final boolean op(Object x) { return type.isInstance(x); } }; } /** * Returns a predicate evaluating to true if its argument is assignable * from (see {@link Class#isAssignableFrom} the given type (class). */ public static Predicate isAssignablePredicate(final Class type) { return new Predicate() { public final boolean op(Object x) { return type.isAssignableFrom(x.getClass()); } }; } /** * Returns a reducer that adds two double elements */ public static DoubleReducer doubleAdder() { return DoubleAdder.adder; } static final class DoubleAdder implements DoubleReducer { static final DoubleAdder adder = new DoubleAdder(); public double op(double a, double b) { return a + b; } } /** * Returns a reducer that adds two long elements */ public static LongReducer longAdder() { return LongAdder.adder; } static final class LongAdder implements LongReducer { static final LongAdder adder = new LongAdder(); public long op(long a, long b) { return a + b; } } /** * Returns a reducer that adds two int elements */ public static IntReducer intAdder() { return IntAdder.adder; } static final class IntAdder implements IntReducer { static final IntAdder adder = new IntAdder(); public int op(int a, int b) { return a + b; } } /** * Returns a generator producing uniform random values between * zero and one, with the same properties as {@link * java.util.Random#nextDouble} but operating independently across * ForkJoinWorkerThreads and usable only within forkjoin * computations. */ public static DoubleGenerator doubleRandom() { return DoubleRandomGenerator.generator; } static final class DoubleRandomGenerator implements DoubleGenerator { static final DoubleRandomGenerator generator = new DoubleRandomGenerator(); public double op() { return ForkJoinWorkerThread.nextRandomDouble(); } } /** * Returns a generator producing uniform random values between * zero and the given bound, with the same properties as {@link * java.util.Random#nextDouble} but operating independently across * ForkJoinWorkerThreads and usable only within forkjoin * computations. * @param bound the upper bound (exclusive) of opd values */ public static DoubleGenerator doubleRandom(double bound) { return new DoubleBoundedRandomGenerator(bound); } static final class DoubleBoundedRandomGenerator implements DoubleGenerator { final double bound; DoubleBoundedRandomGenerator(double bound) { this.bound = bound; } public double op() { return ForkJoinWorkerThread.nextRandomDouble() * bound; } } /** * Returns a generator producing uniform random values between the * given least value (inclusive) and bound (exclusive), operating * independently across ForkJoinWorkerThreads and usable only * within forkjoin computations. * @param least the least value returned * @param bound the upper bound (exclusive) of opd values */ public static DoubleGenerator doubleRandom(double least, double bound) { return new DoubleIntervalRandomGenerator(least, bound); } static final class DoubleIntervalRandomGenerator implements DoubleGenerator { final double least; final double range; DoubleIntervalRandomGenerator(double least, double bound) { this.least = least; this.range = bound - least; } public double op() { return ForkJoinWorkerThread.nextRandomDouble() * range + least; } } /** * Returns a generator producing uniform random values with the * same properties as {@link java.util.Random#nextLong} but * operating independently across ForkJoinWorkerThreads and usable * only within forkjoin computations. */ public static LongGenerator longRandom() { return LongRandomGenerator.generator; } static final class LongRandomGenerator implements LongGenerator { static final LongRandomGenerator generator = new LongRandomGenerator(); public long op() { return ForkJoinWorkerThread.nextRandomLong(); } } /** * Returns a generator producing uniform random values with the * same properties as {@link java.util.Random#nextInt(int)} but * operating independently across ForkJoinWorkerThreads and usable * only within forkjoin computations. * @param bound the upper bound (exclusive) of opd values */ public static LongGenerator longRandom(long bound) { if (bound <= 0) throw new IllegalArgumentException(); return new LongBoundedRandomGenerator(bound); } static final class LongBoundedRandomGenerator implements LongGenerator { final long bound; LongBoundedRandomGenerator(long bound) { this.bound = bound; } public long op() { return ForkJoinWorkerThread.nextRandomLong(bound); } } /** * Returns a generator producing uniform random values between the * given least value (inclusive) and bound (exclusive), operating * independently across ForkJoinWorkerThreads and usable only * within forkjoin computations. * @param least the least value returned * @param bound the upper bound (exclusive) of opd values */ public static LongGenerator longRandom(long least, long bound) { if (least >= bound) throw new IllegalArgumentException(); return new LongIntervalRandomGenerator(least, bound); } static final class LongIntervalRandomGenerator implements LongGenerator { final long least; final long range; LongIntervalRandomGenerator(long least, long bound) { this.least = least; this.range = bound - least; } public long op() { return ForkJoinWorkerThread.nextRandomLong(range) + least; } } /** * Returns a generator producing uniform random values with the * same properties as {@link java.util.Random#nextInt} but * operating independently across ForkJoinWorkerThreads and usable * only within forkjoin computations. */ public static IntGenerator intRandom() { return IntRandomGenerator.generator; } static final class IntRandomGenerator implements IntGenerator { static final IntRandomGenerator generator = new IntRandomGenerator(); public int op() { return ForkJoinWorkerThread.nextRandomInt(); } } /** * Returns a generator producing uniform random values with the * same properties as {@link java.util.Random#nextInt(int)} but * operating independently across ForkJoinWorkerThreads and usable * only within forkjoin computations. * @param bound the upper bound (exclusive) of opd values */ public static IntGenerator intRandom(int bound) { if (bound <= 0) throw new IllegalArgumentException(); return new IntBoundedRandomGenerator(bound); } static final class IntBoundedRandomGenerator implements IntGenerator { final int bound; IntBoundedRandomGenerator(int bound) { this.bound = bound; } public int op() { return ForkJoinWorkerThread.nextRandomInt(bound); } } /** * Returns a generator producing uniform random values between the * given least value (inclusive) and bound (exclusive), operating * independently across ForkJoinWorkerThreads and usable only * within forkjoin computations. * @param least the least value returned * @param bound the upper bound (exclusive) of opd values */ public static IntGenerator intRandom(int least, int bound) { if (least >= bound) throw new IllegalArgumentException(); return new IntIntervalRandomGenerator(least, bound); } static final class IntIntervalRandomGenerator implements IntGenerator { final int least; final int range; IntIntervalRandomGenerator(int least, int bound) { this.least = least; this.range = bound - least; } public int op() { return ForkJoinWorkerThread.nextRandomInt(range) + least; } } /** * Returns a predicate evaluating to true if the * first argument equals the second */ public static BinaryPredicate equalityPredicate() { return EqualityPredicate.predicate; } static final class EqualityPredicate implements BinaryPredicate { static final EqualityPredicate predicate = new EqualityPredicate(); public final boolean op(Object x, Object y) { return x.equals(y); } } /** * Returns a predicate evaluating to true if the * first argument == the second */ public static BinaryPredicate identityPredicate() { return IdentityPredicate.predicate; } static final class IdentityPredicate implements BinaryPredicate { static final IdentityPredicate predicate = new IdentityPredicate(); public final boolean op(Object x, Object y) { return x == y; } } /** * Returns a predicate evaluating to true if the * first argument == the second */ public static BinaryIntPredicate intEqualityPredicate() { return IntEqualityPredicate.predicate; } static final class IntEqualityPredicate implements BinaryIntPredicate { static final IntEqualityPredicate predicate = new IntEqualityPredicate(); public final boolean op(int x, int y) { return x == y; } } /** * Returns a predicate evaluating to true if the * first argument == the second */ public static BinaryLongPredicate longEqualityPredicate() { return LongEqualityPredicate.predicate; } static final class LongEqualityPredicate implements BinaryLongPredicate { static final LongEqualityPredicate predicate = new LongEqualityPredicate(); public final boolean op(long x, long y) { return x == y; } } /** * Returns a predicate evaluating to true if the * first argument == the second */ public static BinaryDoublePredicate doubleEqualityPredicate() { return DoubleEqualityPredicate.predicate; } static final class DoubleEqualityPredicate implements BinaryDoublePredicate { static final DoubleEqualityPredicate predicate = new DoubleEqualityPredicate(); public final boolean op(double x, double y) { return x == y; } } /** * Returns a predicate evaluating to true if the * first argument !equals the second */ public static BinaryPredicate inequalityPredicate() { return InequalityPredicate.predicate; } static final class InequalityPredicate implements BinaryPredicate { static final InequalityPredicate predicate = new InequalityPredicate(); public final boolean op(Object x, Object y) { return !x.equals(y); } } /** * Returns a predicate evaluating to true if the * first argument != the second */ public static BinaryPredicate nonidentityPredicate() { return NonidentityPredicate.predicate; } static final class NonidentityPredicate implements BinaryPredicate { static final NonidentityPredicate predicate = new NonidentityPredicate(); public final boolean op(Object x, Object y) { return x != y; } } /** * Returns a predicate evaluating to true if the * first argument != the second */ public static BinaryIntPredicate intInequalityPredicate() { return IntInequalityPredicate.predicate; } static final class IntInequalityPredicate implements BinaryIntPredicate { static final IntInequalityPredicate predicate = new IntInequalityPredicate(); public final boolean op(int x, int y) { return x != y; } } /** * Returns a predicate evaluating to true if the * first argument == the second */ public static BinaryLongPredicate longInequalityPredicate() { return LongInequalityPredicate.predicate; } static final class LongInequalityPredicate implements BinaryLongPredicate { static final LongInequalityPredicate predicate = new LongInequalityPredicate(); public final boolean op(long x, long y) { return x != y; } } /** * Returns a predicate evaluating to true if the * first argument != the second */ public static BinaryDoublePredicate doubleInequalityPredicate() { return DoubleInequalityPredicate.predicate; } static final class DoubleInequalityPredicate implements BinaryDoublePredicate { static final DoubleInequalityPredicate predicate = new DoubleInequalityPredicate(); public final boolean op(double x, double y) { return x != y; } } }