1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.functor.core.comparator;
18  
19  import java.io.Serializable;
20  import java.util.Comparator;
21  
22  import org.apache.commons.functor.BinaryFunction;
23  import org.apache.commons.functor.UnaryFunction;
24  import org.apache.commons.functor.adapter.RightBoundFunction;
25  import org.apache.commons.lang3.Validate;
26  
27  /**
28   * Adapts a {@link Comparator Comparator} to the
29   * {@link BinaryFunction} interface.
30   *
31   * @param <T> the binary function arguments and return types.
32   * @version $Revision: 1364676 $ $Date: 2012-07-23 12:21:25 -0300 (Mon, 23 Jul 2012) $
33   */
34  public final class Max<T> implements BinaryFunction<T, T, T>, Serializable {
35  
36      /**
37       * Basic Max instance.
38       */
39      public static final Max<Comparable<?>> INSTANCE = Max.<Comparable<?>>instance();
40  
41      /**
42       * serialVersionUID declaration.
43       */
44      private static final long serialVersionUID = 6514424464263828685L;
45  
46      /**
47       * The wrapped comparator.
48       */
49      private final Comparator<T> comparator;
50  
51      /**
52       * Create a new Max.
53       */
54      @SuppressWarnings("unchecked")
55      public Max() {
56          this((Comparator<T>) ComparableComparator.INSTANCE);
57      }
58  
59      /**
60       * Create a new Max.
61       * @param comparator Comparator to use
62       */
63      public Max(Comparator<T> comparator) {
64          this.comparator = Validate.notNull(comparator, "Comparator argument must not be null");
65      }
66  
67      /**
68       * {@inheritDoc}
69       */
70      public T evaluate(T left, T right) {
71          return (comparator.compare(left, right) >= 0) ? left : right;
72      }
73  
74      /**
75       * {@inheritDoc}
76       */
77      @Override
78      public boolean equals(Object that) {
79          return that == this || (that instanceof Max<?> && equals((Max<?>) that));
80      }
81  
82      /**
83       * Learn whether another Max is equal to this.
84       * @param that Max to test
85       * @return boolean
86       */
87      public boolean equals(Max<?> that) {
88          return null != that && comparator.equals(that.comparator);
89      }
90  
91      /**
92       * {@inheritDoc}
93       */
94      @Override
95      public int hashCode() {
96          return "Max".hashCode() ^ comparator.hashCode();
97      }
98  
99      /**
100      * {@inheritDoc}
101      */
102     @Override
103     public String toString() {
104         return "Max<" + comparator + ">";
105     }
106 
107     /**
108      * Get a Max instance.
109      *
110      * @param <T> the binary function arguments and return types.
111      * @return Max
112      */
113     public static <T extends Comparable<?>> Max<T> instance() {
114         return new Max<T>();
115     }
116 
117     /**
118      * Get a Max UnaryFunction.
119      *
120      * @param <T> the binary function arguments and return types.
121      * @param right the right side argument of the Max function
122      * @return UnaryFunction<T, T>
123      */
124     public static <T extends Comparable<?>> UnaryFunction<T, T> instance(T right) {
125         return RightBoundFunction.bind(new Max<T>(), right);
126     }
127 
128 }