001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.functor.core.comparator;
018    
019    import java.io.Serializable;
020    import java.util.Comparator;
021    
022    import org.apache.commons.functor.BinaryPredicate;
023    import org.apache.commons.functor.UnaryPredicate;
024    import org.apache.commons.functor.adapter.RightBoundPredicate;
025    
026    /**
027     * A {@link BinaryPredicate BinaryPredicate} that {@link #test tests}
028     * <code>true</code> iff the left argument is not equal to the
029     * right argument under the specified {@link Comparator}.
030     * When no (or a <code>null</code> <code>Comparator</code> is specified,
031     * a {@link Comparable Comparable} <code>Comparator</code> is used.
032     *
033     * @see org.apache.commons.functor.core.IsEqual
034     *
035     * @version $Revision: 1166347 $ $Date: 2011-09-07 21:48:35 +0200 (Wed, 07 Sep 2011) $
036     * @author Rodney Waldhoff
037     *
038     */
039    public final class IsNotEquivalent<T> implements BinaryPredicate<T, T>, Serializable {
040    
041        /**
042         * Basic IsNotEquivalent instance.
043         */
044        public static final IsNotEquivalent<Comparable<?>> INSTANCE = IsNotEquivalent.<Comparable<?>>instance();
045    
046        /**
047         * serialVersionUID declaration.
048         */
049        private static final long serialVersionUID = 1021154684877529051L;
050    
051        private final Comparator<? super T> comparator;
052    
053        /**
054         * Create a new IsNotEquivalent.
055         */
056        @SuppressWarnings("unchecked")
057        public IsNotEquivalent() {
058            this(ComparableComparator.INSTANCE);
059        }
060    
061        /**
062         * Construct a <code>IsNotEquivalent</code> {@link BinaryPredicate predicate}
063         * for the given {@link Comparator Comparator}.
064         *
065         * @param comparator the {@link Comparator Comparator}, when <code>null</code>,
066         *        a <code>Comparator</code> for {@link Comparable Comparable}s will
067         *        be used.
068         */
069        public IsNotEquivalent(Comparator<? super T> comparator) {
070            if (comparator == null) {
071                throw new IllegalArgumentException("Comparator must not be null");
072            }
073            this.comparator = comparator;
074        }
075    
076        /**
077         * {@inheritDoc}
078         * Return <code>true</code> iff the <i>left</i> parameter is
079         * not equal to the <i>right</i> parameter under my current
080         * {@link Comparator Comparator}.
081         */
082        public boolean test(T left, T right) {
083            return comparator.compare(left, right) != 0;
084        }
085    
086        /**
087         * {@inheritDoc}
088         */
089        public boolean equals(Object that) {
090            return that == this || (that instanceof IsNotEquivalent<?> && equals((IsNotEquivalent<?>) that));
091        }
092    
093        /**
094         * Learn whether another IsNotEquivalent is equal to this.
095         * @param that IsNotEquivalent to test
096         * @return boolean
097         */
098        public boolean equals(IsNotEquivalent<?> that) {
099            if (null != that) {
100                if (null == comparator) {
101                    return null == that.comparator;
102                }
103                return comparator.equals(that.comparator);
104            }
105            return false;
106        }
107    
108        /**
109         * {@inheritDoc}
110         */
111        public int hashCode() {
112            int hash = "IsNotEquivalent".hashCode();
113            // by construction, comparator is never null
114            hash ^= comparator.hashCode();
115            return hash;
116        }
117    
118        /**
119         * {@inheritDoc}
120         */
121        public String toString() {
122            return "IsNotEquivalent<" + comparator + ">";
123        }
124    
125        /**
126         * Get an IsNotEquivalent instance.
127         * @return IsNotEquivalent
128         */
129        @SuppressWarnings("unchecked")
130        public static <T extends Comparable<?>> IsNotEquivalent<T> instance() {
131            return new IsNotEquivalent<T>(ComparableComparator.INSTANCE);
132        }
133    
134        /**
135         * Get an IsNotEquivalent UnaryPredicate.
136         * @param right Comparable against which UnaryPredicate arguments will be compared.
137         * @return UnaryPredicate
138         */
139        public static <T extends Comparable<?>> UnaryPredicate<T> instance(T right) {
140            return RightBoundPredicate.bind(instance(), right);
141        }
142    
143    }