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.BinaryFunction;
023    import org.apache.commons.functor.UnaryFunction;
024    import org.apache.commons.functor.adapter.RightBoundFunction;
025    
026    /**
027     * Adapts a {@link Comparator Comparator} to the
028     * {@link BinaryFunction} interface.
029     *
030     * @version $Revision: 1166353 $ $Date: 2011-09-07 21:53:49 +0200 (Wed, 07 Sep 2011) $
031     * @author Rodney Waldhoff
032     */
033    public final class Max<T> implements BinaryFunction<T, T, T>, Serializable {
034    
035        /**
036         * Basic Max instance.
037         */
038        public static final Max<Comparable<?>> INSTANCE = Max.<Comparable<?>>instance();
039    
040        /**
041         * serialVersionUID declaration.
042         */
043        private static final long serialVersionUID = 6514424464263828685L;
044    
045        private final Comparator<T> comparator;
046    
047        /**
048         * Create a new Max.
049         */
050        @SuppressWarnings("unchecked")
051        public Max() {
052            this(ComparableComparator.instance());
053        }
054    
055        /**
056         * Create a new Max.
057         * @param comparator Comparator to use
058         */
059        public Max(Comparator<T> comparator) {
060            if (comparator == null) {
061                throw new IllegalArgumentException("Comparator argument must not be null");
062            }
063            this.comparator = comparator;
064        }
065    
066        /**
067         * {@inheritDoc}
068         */
069        public T evaluate(T left, T right) {
070            return (comparator.compare(left, right) >= 0) ? left : right;
071        }
072    
073        /**
074         * {@inheritDoc}
075         */
076        public boolean equals(Object that) {
077            return that == this || (that instanceof Max<?> && equals((Max<?>) that));
078        }
079    
080        /**
081         * Learn whether another Max is equal to this.
082         * @param that Max to test
083         * @return boolean
084         */
085        public boolean equals(Max<?> that) {
086            return null != that && comparator.equals(that.comparator);
087        }
088    
089        /**
090         * {@inheritDoc}
091         */
092        public int hashCode() {
093            return "Max".hashCode() ^ comparator.hashCode();
094        }
095    
096        /**
097         * {@inheritDoc}
098         */
099        public String toString() {
100            return "Max<" + comparator + ">";
101        }
102    
103        /**
104         * Get a Max instance.
105         * @return Max
106         */
107        public static <T extends Comparable<?>> Max<T> instance() {
108            return new Max<T>();
109        }
110    
111        /**
112         * Get a Max UnaryFunction.
113         * @param right the right side argument of the Max function
114         * @return UnaryFunction<T, T>
115         */
116        public static <T extends Comparable<?>> UnaryFunction<T, T> instance(T right) {
117            return RightBoundFunction.bind(new Max<T>(), right);
118        }
119    
120    }