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

com.gs.collections.impl.block.factory.Predicates Maven / Gradle / Ivy

Go to download

GS Collections is a collections framework for Java. It has JDK-compatible List, Set and Map implementations with a rich API and set of utility classes that work with any JDK compatible Collections, Arrays, Maps or Strings. The iteration protocol was inspired by the Smalltalk collection framework.

There is a newer version: 7.0.3
Show newest version
/*
 * Copyright 2015 Goldman Sachs.
 *
 * 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.gs.collections.impl.block.factory;

import java.util.Arrays;
import java.util.Collection;
import java.util.Set;

import com.gs.collections.api.block.function.Function;
import com.gs.collections.api.block.predicate.Predicate;
import com.gs.collections.api.block.predicate.Predicate2;
import com.gs.collections.api.set.SetIterable;
import com.gs.collections.impl.block.predicate.checked.CheckedPredicate;
import com.gs.collections.impl.block.predicate.checked.ThrowingPredicate;
import com.gs.collections.impl.set.mutable.UnifiedSet;
import com.gs.collections.impl.utility.Iterate;

/**
 * The Predicates class can be used to build common Predicates to be used by methods such
 * as detect:, select: and reject: on the Iterate, MapIterate, and ArrayIterate classes.  Predicates supports
 * equals, not equals, less than, greater than, less than or equal to, greater than or equal to, in, not in
 * and, or, and several other Predicate type operations.
 */
public abstract class Predicates
        implements Predicate
{
    private static final long serialVersionUID = 1L;
    private static final Predicates ALWAYS_TRUE = new AlwaysTrue();
    private static final Predicates ALWAYS_FALSE = new AlwaysFalse();
    private static final Predicates IS_NULL = new IsNull();
    private static final Predicates NOT_NULL = new NotNull();
    private static final int SMALL_COLLECTION_THRESHOLD = 6;

    public static  Predicates adapt(Predicate predicate)
    {
        return new PredicateAdapter(predicate);
    }

    /**
     * Allows a Java 8 lambda or method reference to be used in a method taking a predicate without requiring an actual cast.
     * This method can be used in places where two or more method overloads could apply when used with a lambda or method
     * reference (e.g. removeIf).
     */
    public static  Predicate cast(Predicate predicate)
    {
        return predicate;
    }

    public static  Predicate throwing(ThrowingPredicate throwingPredicate)
    {
        return new ThrowingPredicateAdapter(throwingPredicate);
    }

    public static  Predicate bind(Predicate2 predicate, P parameter)
    {
        return new BindPredicate2(predicate, parameter);
    }

    public static  Predicate synchronizedEach(Predicate predicate)
    {
        return new SynchronizedPredicate(predicate);
    }

    public static  Predicates or(Iterable> predicates)
    {
        return new OrIterablePredicate(predicates);
    }

    public static  Predicates or(Predicate predicate1, Predicate predicate2)
    {
        return new OrPredicate(predicate1, predicate2);
    }

    public static  Predicates or(Predicate... predicates)
    {
        return new OrIterablePredicate(Arrays.asList(predicates));
    }

    public static  Predicates and(Iterable> predicates)
    {
        return new AndIterablePredicate(predicates);
    }

    public static  Predicates and(Predicate predicate1, Predicate predicate2)
    {
        return new AndPredicate(predicate1, predicate2);
    }

    public static  Predicates and(Predicate... predicates)
    {
        return new AndIterablePredicate(Arrays.asList(predicates));
    }

    public static  Predicates not(Predicate predicate)
    {
        return new NotPredicate(predicate);
    }

    public Predicates not()
    {
        return Predicates.not(this);
    }

    public static  Predicates neither(Predicate operation1, Predicate operation2)
    {
        return new NeitherPredicate(operation1, operation2);
    }

    public static  Predicates noneOf(Predicate... operations)
    {
        return new NoneOfIterablePredicate(Arrays.asList(operations));
    }

    public static  Predicates noneOf(Iterable> operations)
    {
        return new NoneOfIterablePredicate(operations);
    }

    /**
     * Tests for equality.
     */
    public static Predicates equal(Object object)
    {
        if (object == null)
        {
            return Predicates.isNull();
        }
        return new EqualPredicate(object);
    }

    /**
     * Creates a predicate which returns true if an object passed to accept method is within the range, inclusive
     * of the from and to values.
     */
    public static > Predicates betweenInclusive(T from, T to)
    {
        Predicates.failIfDifferentTypes(from, to);
        return new BetweenInclusive(from, to);
    }

    private static void failIfDifferentTypes(Object from, Object to)
    {
        if (!from.getClass().equals(to.getClass()))
        {
            throw new IllegalArgumentException("Trying to do a between comparison with two different types "
                    + from.getClass()
                    + ':'
                    + to.getClass());
        }
    }

    /**
     * Creates a predicate which returns true if an object passed to accept method is within the range, exclusive
     * of the from and to values.
     */
    public static > Predicates betweenExclusive(T from, T to)
    {
        Predicates.failIfDifferentTypes(from, to);
        return new BetweenExclusive(from, to);
    }

    /**
     * Creates a predicate which returns true if an object passed to accept method is within the range, inclusive
     * of the from and exclusive from the to value.
     */
    public static > Predicates betweenInclusiveFrom(T from, T to)
    {
        Predicates.failIfDifferentTypes(from, to);
        return new BetweenInclusiveFrom(from, to);
    }

    /**
     * Creates a predicate which returns true if an object passed to accept method is within the range, exclusive
     * of the from and inclusive of the to value.
     */
    public static > Predicates betweenInclusiveTo(T from, T to)
    {
        Predicates.failIfDifferentTypes(from, to);
        return new BetweenInclusiveTo(from, to);
    }

    /**
     * Creates a predicate which returns true if an object passed to accept method is contained in the iterable.
     */
    public static Predicates in(Iterable iterable)
    {
        if (iterable instanceof SetIterable)
        {
            return new InSetIterablePredicate((SetIterable) iterable);
        }
        if (iterable instanceof Set)
        {
            return new InSetPredicate((Set) iterable);
        }
        if (iterable instanceof Collection && ((Collection) iterable).size() <= SMALL_COLLECTION_THRESHOLD)
        {
            return new InCollectionPredicate((Collection) iterable);
        }
        return new InSetIterablePredicate(UnifiedSet.newSet(iterable));
    }

    public static Predicates in(Object... array)
    {
        if (array.length <= SMALL_COLLECTION_THRESHOLD)
        {
            return new InCollectionPredicate(Arrays.asList(array));
        }
        return new InSetIterablePredicate(UnifiedSet.newSetWith(array));
    }

    /**
     * Creates a predicate which returns true if an attribute selected from an object passed to accept method
     * is contained in the iterable.
     */
    public static  Predicates attributeIn(
            Function function,
            Iterable iterable)
    {
        return new AttributePredicate(function, Predicates.in(iterable));
    }

    public static > Predicates attributeBetweenInclusive(
            Function function,
            V from,
            V to)
    {
        return new AttributePredicate(function, Predicates.betweenInclusive(from, to));
    }

    public static > Predicates attributeBetweenExclusive(
            Function function,
            V from,
            V to)
    {
        return new AttributePredicate(function, Predicates.betweenExclusive(from, to));
    }

    public static > Predicates attributeBetweenInclusiveFrom(
            Function function,
            V from,
            V to)
    {
        return new AttributePredicate(function, Predicates.betweenInclusiveFrom(from, to));
    }

    public static > Predicates attributeBetweenInclusiveTo(
            Function function,
            V from,
            V to)
    {
        return new AttributePredicate(function, Predicates.betweenInclusiveTo(from, to));
    }

    /**
     * Creates a predicate which returns true if an object passed to accept method is not contained in
     * the iterable.
     */
    public static Predicates notIn(Iterable iterable)
    {
        if (iterable instanceof SetIterable)
        {
            return new NotInSetIterablePredicate((SetIterable) iterable);
        }
        if (iterable instanceof Set)
        {
            return new NotInSetPredicate((Set) iterable);
        }
        if (iterable instanceof Collection && ((Collection) iterable).size() <= SMALL_COLLECTION_THRESHOLD)
        {
            return new NotInCollectionPredicate((Collection) iterable);
        }
        return new NotInSetIterablePredicate(UnifiedSet.newSet(iterable));
    }

    public static Predicates notIn(Object... array)
    {
        if (array.length <= SMALL_COLLECTION_THRESHOLD)
        {
            return new NotInCollectionPredicate(Arrays.asList(array));
        }
        return new NotInSetIterablePredicate(UnifiedSet.newSetWith(array));
    }

    /**
     * Creates a predicate which returns true if an attribute selected from an object passed to accept method
     * is not contained in the iterable.
     */
    public static  Predicates attributeNotIn(
            Function function,
            Iterable iterable)
    {
        return new AttributePredicate(function, Predicates.notIn(iterable));
    }

    public static > Predicates lessThan(T object)
    {
        return new LessThanPredicate(object);
    }

    public static > Predicates attributeLessThan(
            Function function,
            V object)
    {
        return new AttributePredicate(function, new LessThanPredicate(object));
    }

    public static > Predicates lessThanOrEqualTo(T object)
    {
        return new LessThanOrEqualPredicate(object);
    }

    public static > Predicates attributeLessThanOrEqualTo(
            Function function,
            V object)
    {
        return new AttributePredicate(function, new LessThanOrEqualPredicate(object));
    }

    public static > Predicates greaterThan(T object)
    {
        return new GreaterThanPredicate(object);
    }

    public static > Predicates attributeGreaterThan(
            Function function,
            V object)
    {
        return new AttributePredicate(function, new GreaterThanPredicate(object));
    }

    public static > Predicates greaterThanOrEqualTo(T object)
    {
        return new GreaterThanOrEqualPredicate(object);
    }

    public static > Predicates attributeGreaterThanOrEqualTo(
            Function function,
            V object)
    {
        return new AttributePredicate(function, new GreaterThanOrEqualPredicate(object));
    }

    public static  Predicates attributePredicate(
            Function function,
            Predicate predicate)
    {
        return new AttributePredicate(function, predicate);
    }

    public static  Predicates attributeEqual(
            Function function,
            Object object)
    {
        return new AttributePredicate(function, Predicates.equal(object));
    }

    public static  Predicates> anySatisfy(Predicate predicate)
    {
        return new AnySatisfy(predicate);
    }

    public static  Predicates> allSatisfy(Predicate predicate)
    {
        return new AllSatisfy(predicate);
    }

    public static  Predicates> noneSatisfy(Predicate predicate)
    {
        return new NoneSatisfy(predicate);
    }

    public static  Predicates attributeAnySatisfy(
            Function> function,
            Predicate predicate)
    {
        return Predicates.attributePredicate(function, Predicates.anySatisfy(predicate));
    }

    public static  Predicates attributeAllSatisfy(
            Function> function,
            Predicate predicate)
    {
        return Predicates.attributePredicate(function, Predicates.allSatisfy(predicate));
    }

    public static  Predicates attributeNoneSatisfy(
            Function> function,
            Predicate predicate)
    {
        return Predicates.attributePredicate(function, Predicates.noneSatisfy(predicate));
    }

    public static Predicates notEqual(Object object)
    {
        if (object == null)
        {
            return Predicates.notNull();
        }
        return new NotEqualPredicate(object);
    }

    public static  Predicates ifTrue(Function function)
    {
        return new AttributeTrue(function);
    }

    public static  Predicates ifFalse(Function function)
    {
        return new AttributeFalse(function);
    }

    public static  Predicates attributeNotEqual(
            Function function,
            Object object)
    {
        return new AttributePredicate(function, Predicates.notEqual(object));
    }

    public static Predicates isNull()
    {
        return IS_NULL;
    }

    public static  Predicates attributeIsNull(Function function)
    {
        return new AttributePredicate(function, Predicates.isNull());
    }

    public static Predicates notNull()
    {
        return NOT_NULL;
    }

    public static  Predicates attributeNotNull(Function function)
    {
        return new AttributePredicate(function, Predicates.notNull());
    }

    public static Predicates sameAs(Object object)
    {
        return new IdentityPredicate(object);
    }

    public static Predicates notSameAs(Object object)
    {
        return new NotIdentityPredicate(object);
    }

    public static Predicates instanceOf(Class clazz)
    {
        return new InstanceOfPredicate(clazz);
    }

    public static Predicates assignableFrom(Class clazz)
    {
        return new AssignableFromPredicate(clazz);
    }

    public static Predicates notInstanceOf(Class clazz)
    {
        return new NotInstanceOfPredicate(clazz);
    }

    public static Predicates alwaysTrue()
    {
        return ALWAYS_TRUE;
    }

    public static Predicates alwaysFalse()
    {
        return ALWAYS_FALSE;
    }

    public Predicates and(Predicate op)
    {
        return Predicates.and(this, op);
    }

    public Predicates or(Predicate op)
    {
        return Predicates.or(this, op);
    }

    public static Predicates> subClass(Class aClass)
    {
        return new SubclassPredicate(aClass);
    }

    public static Predicates> superClass(Class aClass)
    {
        return new SuperclassPredicate(aClass);
    }

    private static final class PredicateAdapter
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Predicate predicate;

        private PredicateAdapter(Predicate newPredicate)
        {
            this.predicate = newPredicate;
        }

        public boolean accept(T o)
        {
            return this.predicate.accept(o);
        }

        @Override
        public String toString()
        {
            return "Predicates.adapt(" + this.predicate + ')';
        }
    }

    protected static class AttributePredicate extends Predicates
    {
        private static final long serialVersionUID = 1L;
        protected final Function function;
        protected final Predicate predicate;

        protected AttributePredicate(
                Function newFunction,
                Predicate newPredicate)
        {
            this.function = newFunction;
            this.predicate = newPredicate;
        }

        public boolean accept(T anObject)
        {
            return this.predicate.accept(this.function.valueOf(anObject));
        }

        @Override
        public String toString()
        {
            return "Predicates.attributePredicate("
                    + this.function
                    + ", "
                    + this.predicate
                    + ')';
        }
    }

    private static class FalseEquals implements Predicate
    {
        private static final long serialVersionUID = 1L;

        public boolean accept(Boolean anObject)
        {
            return Boolean.FALSE.equals(anObject);
        }
    }

    private static class TrueEquals implements Predicate
    {
        private static final long serialVersionUID = 1L;

        public boolean accept(Boolean anObject)
        {
            return Boolean.TRUE.equals(anObject);
        }
    }

    private static final class AttributeFalse extends AttributePredicate
    {
        private static final long serialVersionUID = 1L;
        private static final FalseEquals FALSE_EQUALS = new FalseEquals();

        private AttributeFalse(Function newFunction)
        {
            super(newFunction, FALSE_EQUALS);
        }

        @Override
        public String toString()
        {
            return "Predicates.ifFalse(" + this.function + ')';
        }
    }

    private static final class AttributeTrue extends AttributePredicate
    {
        private static final long serialVersionUID = 1L;
        private static final TrueEquals TRUE_EQUALS = new TrueEquals();

        private AttributeTrue(Function newFunction)
        {
            super(newFunction, TRUE_EQUALS);
        }

        @Override
        public String toString()
        {
            return "Predicates.ifTrue(" + this.function + ')';
        }
    }

    public static class AnySatisfy extends Predicates>
    {
        private static final long serialVersionUID = 1L;
        private final Predicate predicate;

        public AnySatisfy(Predicate predicate)
        {
            this.predicate = predicate;
        }

        public boolean accept(Iterable iterable)
        {
            return Iterate.anySatisfy(iterable, this.predicate);
        }
    }

    public static class AllSatisfy extends Predicates>
    {
        private static final long serialVersionUID = 1L;
        private final Predicate predicate;

        public AllSatisfy(Predicate predicate)
        {
            this.predicate = predicate;
        }

        public boolean accept(Iterable iterable)
        {
            return Iterate.allSatisfy(iterable, this.predicate);
        }
    }

    public static class NoneSatisfy extends Predicates>
    {
        private static final long serialVersionUID = 1L;
        private final Predicate predicate;

        public NoneSatisfy(Predicate predicate)
        {
            this.predicate = predicate;
        }

        public boolean accept(Iterable iterable)
        {
            return Iterate.noneSatisfy(iterable, this.predicate);
        }
    }

    private abstract static class CompareToPredicate>
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        protected final T compareTo;

        private CompareToPredicate(T newCompareTo)
        {
            this.compareTo = newCompareTo;
        }
    }

    protected static class LessThanPredicate>
            extends CompareToPredicate
    {
        private static final long serialVersionUID = 1L;

        protected LessThanPredicate(T newCompareTo)
        {
            super(newCompareTo);
        }

        public boolean accept(T o)
        {
            return o.compareTo(this.compareTo) < 0;
        }

        @Override
        public String toString()
        {
            return "Predicates.lessThan(" + this.compareTo + ')';
        }
    }

    protected abstract static class RangePredicate>
            extends CompareToPredicate
    {
        private static final long serialVersionUID = 1L;
        protected final T compareFrom;

        protected RangePredicate(T newCompareFrom, T newCompareTo)
        {
            super(newCompareTo);
            this.compareFrom = newCompareFrom;
        }
    }

    private static final class BetweenInclusive>
            extends RangePredicate
    {
        private static final long serialVersionUID = 1L;

        private BetweenInclusive(T newCompareFrom, T newCompareTo)
        {
            super(newCompareFrom, newCompareTo);
        }

        public boolean accept(T o)
        {
            return o.compareTo(this.compareFrom) >= 0 && o.compareTo(this.compareTo) <= 0;
        }
    }

    private static final class BetweenInclusiveTo>
            extends RangePredicate
    {
        private static final long serialVersionUID = 1L;

        private BetweenInclusiveTo(T newCompareFrom, T newCompareTo)
        {
            super(newCompareFrom, newCompareTo);
        }

        public boolean accept(T o)
        {
            return o.compareTo(this.compareFrom) > 0 && o.compareTo(this.compareTo) <= 0;
        }
    }

    private static final class BetweenInclusiveFrom>
            extends RangePredicate
    {
        private static final long serialVersionUID = 1L;

        private BetweenInclusiveFrom(T newCompareFrom, T newCompareTo)
        {
            super(newCompareFrom, newCompareTo);
        }

        public boolean accept(T o)
        {
            return o.compareTo(this.compareFrom) >= 0 && o.compareTo(this.compareTo) < 0;
        }
    }

    private static final class BetweenExclusive>
            extends RangePredicate
    {
        private static final long serialVersionUID = 1L;

        private BetweenExclusive(T newCompareFrom, T newCompareTo)
        {
            super(newCompareFrom, newCompareTo);
        }

        public boolean accept(T o)
        {
            return o.compareTo(this.compareFrom) > 0 && o.compareTo(this.compareTo) < 0;
        }
    }

    protected static class LessThanOrEqualPredicate>
            extends CompareToPredicate
    {
        private static final long serialVersionUID = 1L;

        protected LessThanOrEqualPredicate(T newCompareTo)
        {
            super(newCompareTo);
        }

        public boolean accept(T o)
        {
            return o.compareTo(this.compareTo) <= 0;
        }

        @Override
        public String toString()
        {
            return "Predicates.lessThanOrEqualTo(" + this.compareTo + ')';
        }
    }

    protected static class GreaterThanPredicate>
            extends CompareToPredicate
    {
        private static final long serialVersionUID = 1L;

        protected GreaterThanPredicate(T newCompareTo)
        {
            super(newCompareTo);
        }

        public boolean accept(T o)
        {
            return o.compareTo(this.compareTo) > 0;
        }

        @Override
        public String toString()
        {
            return "Predicates.greaterThan(" + this.compareTo + ')';
        }
    }

    protected static class GreaterThanOrEqualPredicate>
            extends CompareToPredicate
    {
        private static final long serialVersionUID = 1L;

        protected GreaterThanOrEqualPredicate(T newCompareTo)
        {
            super(newCompareTo);
        }

        public boolean accept(T o)
        {
            return o.compareTo(this.compareTo) >= 0;
        }

        @Override
        public String toString()
        {
            return "Predicates.greaterThanOrEqualTo(" + this.compareTo + ')';
        }
    }

    private static final class AndIterablePredicate
            extends AbstractIterablePredicate
    {
        private static final long serialVersionUID = 1L;

        private AndIterablePredicate(Iterable> predicates)
        {
            super(predicates);
        }

        @Override
        protected String getTypeName()
        {
            return "and";
        }

        public boolean accept(final T anObject)
        {
            Predicate> predicate = new Predicate>()
            {
                public boolean accept(Predicate aPredicate)
                {
                    return aPredicate.accept(anObject);
                }
            };
            return Iterate.allSatisfy(this.predicates, predicate);
        }
    }

    private static final class OrIterablePredicate
            extends AbstractIterablePredicate
    {
        private static final long serialVersionUID = 1L;

        private OrIterablePredicate(Iterable> predicates)
        {
            super(predicates);
        }

        @Override
        protected String getTypeName()
        {
            return "or";
        }

        public boolean accept(final T anObject)
        {
            Predicate> predicate = new Predicate>()
            {
                public boolean accept(Predicate aPredicate)
                {
                    return aPredicate.accept(anObject);
                }
            };
            return Iterate.anySatisfy(this.predicates, predicate);
        }
    }

    private static final class NoneOfIterablePredicate
            extends AbstractIterablePredicate
    {
        private static final long serialVersionUID = 1L;

        private NoneOfIterablePredicate(Iterable> predicates)
        {
            super(predicates);
        }

        @Override
        protected String getTypeName()
        {
            return "noneOf";
        }

        public boolean accept(final T anObject)
        {
            Predicate> predicate = new Predicate>()
            {
                public boolean accept(Predicate aPredicate)
                {
                    return !aPredicate.accept(anObject);
                }
            };
            return Iterate.allSatisfy(this.predicates, predicate);
        }
    }

    private abstract static class AbstractIterablePredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        protected final Iterable> predicates;

        private AbstractIterablePredicate(Iterable> predicates)
        {
            this.predicates = predicates;
        }

        protected abstract String getTypeName();

        @Override
        public String toString()
        {
            return "Predicates." + this.getTypeName() + '(' + this.predicates + ')';
        }
    }

    private static final class AndPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Predicate left;
        private final Predicate right;

        private AndPredicate(Predicate one, Predicate two)
        {
            this.left = one;
            this.right = two;
        }

        public boolean accept(T anObject)
        {
            return this.left.accept(anObject) && this.right.accept(anObject);
        }

        @Override
        public String toString()
        {
            return this.left + ".and(" + this.right + ')';
        }
    }

    private static final class NeitherPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Predicate left;
        private final Predicate right;

        private NeitherPredicate(Predicate one, Predicate two)
        {
            this.left = one;
            this.right = two;
        }

        public boolean accept(T anObject)
        {
            return !this.left.accept(anObject) && !this.right.accept(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.neither(" + this.left + ", " + this.right + ')';
        }
    }

    private static final class OrPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Predicate left;
        private final Predicate right;

        private OrPredicate(Predicate one, Predicate two)
        {
            this.left = one;
            this.right = two;
        }

        public boolean accept(T anObject)
        {
            return this.left.accept(anObject) || this.right.accept(anObject);
        }

        @Override
        public String toString()
        {
            return this.left + ".or(" + this.right + ')';
        }
    }

    private static final class NotPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Predicate predicate;

        private NotPredicate(Predicate newPredicate)
        {
            this.predicate = newPredicate;
        }

        public boolean accept(T anObject)
        {
            return !this.predicate.accept(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.not(" + this.predicate + ')';
        }
    }

    private static final class EqualPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Object compareObject;

        private EqualPredicate(Object newCompareObject)
        {
            this.compareObject = newCompareObject;
        }

        public boolean accept(Object anObject)
        {
            return this.compareObject.equals(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.equal(" + this.compareObject + ')';
        }
    }

    private static final class InCollectionPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Collection collection;

        private InCollectionPredicate(Collection collection)
        {
            this.collection = collection;
        }

        public boolean accept(Object anObject)
        {
            return this.collection.contains(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.in(" + this.collection + ')';
        }
    }

    private static final class NotInCollectionPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Collection collection;

        private NotInCollectionPredicate(Collection collection)
        {
            this.collection = collection;
        }

        public boolean accept(Object anObject)
        {
            return !this.collection.contains(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.notIn(" + this.collection + ')';
        }
    }

    private static final class InSetIterablePredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final SetIterable setIterable;

        private InSetIterablePredicate(SetIterable setIterable)
        {
            this.setIterable = setIterable;
        }

        public boolean accept(Object anObject)
        {
            return this.setIterable.contains(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.in(" + this.setIterable + ')';
        }
    }

    private static final class NotInSetIterablePredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final SetIterable setIterable;

        private NotInSetIterablePredicate(SetIterable setIterable)
        {
            this.setIterable = setIterable;
        }

        public boolean accept(Object anObject)
        {
            return !this.setIterable.contains(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.notIn(" + this.setIterable + ')';
        }
    }

    private static final class InSetPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Set set;

        private InSetPredicate(Set set)
        {
            this.set = set;
        }

        public boolean accept(Object anObject)
        {
            return this.set.contains(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.in(" + this.set + ')';
        }
    }

    private static final class NotInSetPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Set set;

        private NotInSetPredicate(Set set)
        {
            this.set = set;
        }

        public boolean accept(Object anObject)
        {
            return !this.set.contains(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.notIn(" + this.set + ')';
        }
    }

    private static final class NotEqualPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Object compareObject;

        private NotEqualPredicate(Object newCompareObject)
        {
            this.compareObject = newCompareObject;
        }

        public boolean accept(Object anObject)
        {
            return !this.compareObject.equals(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.notEqual(" + this.compareObject + ')';
        }
    }

    private static final class IsNull
            extends Predicates
    {
        private static final long serialVersionUID = 1L;

        public boolean accept(Object anObject)
        {
            return anObject == null;
        }

        @Override
        public String toString()
        {
            return "Predicates.isNull()";
        }
    }

    private static final class NotNull
            extends Predicates
    {
        private static final long serialVersionUID = 1L;

        public boolean accept(Object anObject)
        {
            return anObject != null;
        }

        @Override
        public String toString()
        {
            return "Predicates.notNull()";
        }
    }

    private static final class AssignableFromPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Class clazz;

        private AssignableFromPredicate(Class newClass)
        {
            this.clazz = newClass;
        }

        public boolean accept(Object anObject)
        {
            return this.clazz.isAssignableFrom(anObject.getClass());
        }

        @Override
        public String toString()
        {
            return "Predicates.assignableFrom(" + this.clazz.getName() + ".class)";
        }
    }

    private static final class InstanceOfPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Class clazz;

        private InstanceOfPredicate(Class newClass)
        {
            this.clazz = newClass;
        }

        public boolean accept(Object anObject)
        {
            return this.clazz.isInstance(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.instanceOf(" + this.clazz.getName() + ".class)";
        }
    }

    private static final class NotInstanceOfPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Class clazz;

        private NotInstanceOfPredicate(Class newClass)
        {
            this.clazz = newClass;
        }

        public boolean accept(Object anObject)
        {
            return !this.clazz.isInstance(anObject);
        }

        @Override
        public String toString()
        {
            return "Predicates.notInstanceOf(" + this.clazz.getName() + ".class)";
        }
    }

    private static final class AlwaysTrue
            extends Predicates
    {
        private static final long serialVersionUID = 1L;

        public boolean accept(Object anObject)
        {
            return true;
        }

        @Override
        public String toString()
        {
            return "Predicates.alwaysTrue()";
        }
    }

    private static final class AlwaysFalse
            extends Predicates
    {
        private static final long serialVersionUID = 1L;

        public boolean accept(Object anObject)
        {
            return false;
        }

        @Override
        public String toString()
        {
            return "Predicates.alwaysFalse()";
        }
    }

    private static final class IdentityPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Object twin;

        private IdentityPredicate(Object object)
        {
            this.twin = object;
        }

        public boolean accept(Object anObject)
        {
            return this.twin == anObject;
        }

        @Override
        public String toString()
        {
            return "Predicates.sameAs(" + this.twin + ')';
        }
    }

    private static final class NotIdentityPredicate
            extends Predicates
    {
        private static final long serialVersionUID = 1L;
        private final Object twin;

        private NotIdentityPredicate(Object object)
        {
            this.twin = object;
        }

        public boolean accept(Object anObject)
        {
            return this.twin != anObject;
        }

        @Override
        public String toString()
        {
            return "Predicates.notSameAs(" + this.twin + ')';
        }
    }

    private static final class SynchronizedPredicate implements Predicate
    {
        private static final long serialVersionUID = 1L;
        private final Predicate predicate;

        private SynchronizedPredicate(Predicate predicate)
        {
            this.predicate = predicate;
        }

        public boolean accept(T each)
        {
            synchronized (each)
            {
                return this.predicate.accept(each);
            }
        }
    }

    private static final class SubclassPredicate extends Predicates>
    {
        private static final long serialVersionUID = 1L;

        private final Class aClass;

        private SubclassPredicate(Class aClass)
        {
            this.aClass = aClass;
        }

        public boolean accept(Class each)
        {
            return this.aClass.isAssignableFrom(each);
        }
    }

    private static final class SuperclassPredicate extends Predicates>
    {
        private static final long serialVersionUID = 1L;

        private final Class aClass;

        private SuperclassPredicate(Class aClass)
        {
            this.aClass = aClass;
        }

        public boolean accept(Class each)
        {
            return each.isAssignableFrom(this.aClass);
        }
    }

    private static final class BindPredicate2 implements Predicate
    {
        private static final long serialVersionUID = 1L;

        private final Predicate2 predicate;
        private final P parameter;

        private BindPredicate2(Predicate2 predicate, P parameter)
        {
            this.predicate = predicate;
            this.parameter = parameter;
        }

        public boolean accept(T each)
        {
            return this.predicate.accept(each, this.parameter);
        }

        @Override
        public String toString()
        {
            return "Predicates.bind(" + this.predicate + ", " + this.parameter + ")";
        }
    }

    private static final class ThrowingPredicateAdapter extends CheckedPredicate
    {
        private static final long serialVersionUID = 1L;
        private final ThrowingPredicate throwingPredicate;

        private ThrowingPredicateAdapter(ThrowingPredicate throwingPredicate)
        {
            this.throwingPredicate = throwingPredicate;
        }

        public boolean safeAccept(T object) throws Exception
        {
            return this.throwingPredicate.safeAccept(object);
        }
    }
}