View Javadoc

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.collections;
18  
19  import java.util.Collection;
20  import java.util.Comparator;
21  
22  import org.apache.commons.collections.comparators.BooleanComparator;
23  import org.apache.commons.collections.comparators.ComparableComparator;
24  import org.apache.commons.collections.comparators.ComparatorChain;
25  import org.apache.commons.collections.comparators.NullComparator;
26  import org.apache.commons.collections.comparators.ReverseComparator;
27  import org.apache.commons.collections.comparators.TransformingComparator;
28  
29  /**
30   * Provides convenient static utility methods for <Code>Comparator</Code>
31   * objects.
32   * <p>
33   * Most of the functionality in this class can also be found in the 
34   * <code>comparators</code> package. This class merely provides a 
35   * convenient central place if you have use for more than one class
36   * in the <code>comparators</code> subpackage.
37   *
38   * @since 2.1
39   * @version $Id: ComparatorUtils.java 1436305 2013-01-21 12:33:10Z tn $
40   */
41  public class ComparatorUtils {
42  
43      /**
44       * ComparatorUtils should not normally be instantiated.
45       */
46      public ComparatorUtils() {
47      }
48  
49      /**
50       * Comparator for natural sort order.
51       *
52       * @see ComparableComparator#comparableComparator()
53       */
54      @SuppressWarnings({ "unchecked", "rawtypes" })
55      public static final Comparator NATURAL_COMPARATOR = ComparableComparator.<Comparable>comparableComparator();
56  
57      /**
58       * Gets a comparator that uses the natural order of the objects.
59       *
60       * @param <E>  the object type to compare
61       * @return  a comparator which uses natural order
62       */
63      @SuppressWarnings("unchecked")
64      public static <E extends Comparable<? super E>> Comparator<E> naturalComparator() {
65          return NATURAL_COMPARATOR;
66      }
67  
68      /**
69       * Gets a comparator that compares using two {@link Comparator}s.
70       * <p>
71       * The second comparator is used if the first comparator returns equal.
72       *
73       * @param <E>  the object type to compare
74       * @param comparator1  the first comparator to use, not null
75       * @param comparator2  the first comparator to use, not null
76       * @return a {@link ComparatorChain} formed from the two comparators
77       * @throws NullPointerException if either comparator is null
78       * @see ComparatorChain
79       */
80      @SuppressWarnings("unchecked")
81      public static <E extends Comparable<? super E>> Comparator<E> chainedComparator(final Comparator<E> comparator1,
82                                                                                      final Comparator<E> comparator2) {
83          return chainedComparator(new Comparator[] {comparator1, comparator2});
84      }
85  
86      /**
87       * Gets a comparator that compares using an array of {@link Comparator}s, applied
88       * in sequence until one returns not equal or the array is exhausted.
89       *
90       * @param <E>  the object type to compare
91       * @param comparators  the comparators to use, not null or empty or containing nulls
92       * @return a {@link ComparatorChain} formed from the input comparators
93       * @throws NullPointerException if comparators array is null or contains a null
94       * @see ComparatorChain
95       */
96      public static <E extends Comparable<? super E>> Comparator<E> chainedComparator(
97              final Comparator<E>[] comparators) {
98  
99          final ComparatorChain<E> chain = new ComparatorChain<E>();
100         for (final Comparator<E> comparator : comparators) {
101             if (comparator == null) {
102                 throw new NullPointerException("Comparator cannot be null");
103             }
104             chain.addComparator(comparator);
105         }
106         return chain;
107     }
108 
109     /**
110      * Gets a comparator that compares using a collection of {@link Comparator}s,
111      * applied in (default iterator) sequence until one returns not equal or the 
112      * collection is exhausted.
113      *
114      * @param <E>  the object type to compare
115      * @param comparators  the comparators to use, not null or empty or containing nulls
116      * @return a {@link ComparatorChain} formed from the input comparators
117      * @throws NullPointerException if comparators collection is null or contains a null
118      * @throws ClassCastException if the comparators collection contains the wrong object type
119      * @see ComparatorChain
120      */
121     @SuppressWarnings("unchecked")
122     public static <E extends Comparable<? super E>> Comparator<E> chainedComparator(
123             final Collection<Comparator<E>> comparators) {
124         
125         return chainedComparator(
126             (Comparator<E>[]) comparators.toArray(new Comparator[comparators.size()])
127         );
128     }
129 
130     /**
131      * Gets a comparator that reverses the order of the given comparator.
132      *
133      * @param <E>  the object type to compare
134      * @param comparator  the comparator to reverse
135      * @return  a comparator that reverses the order of the input comparator
136      * @see ReverseComparator
137      */
138     public static <E> Comparator<E> reversedComparator(final Comparator<E> comparator) {
139         return new ReverseComparator<E>(comparator);
140     }
141 
142     /**
143      * Gets a Comparator that can sort Boolean objects.
144      * <p>
145      * The parameter specifies whether true or false is sorted first.
146      * <p>
147      * The comparator throws NullPointerException if a null value is compared.
148      * 
149      * @param trueFirst  when <code>true</code>, sort 
150      *        <code>true</code> {@link Boolean}s before
151      *        <code>false</code> {@link Boolean}s.
152      * @return  a comparator that sorts booleans
153      */
154     public static Comparator<Boolean> booleanComparator(final boolean trueFirst) {
155         return BooleanComparator.booleanComparator(trueFirst);
156     }
157     
158     /**
159      * Gets a Comparator that controls the comparison of <code>null</code> values.
160      * <p>
161      * The returned comparator will consider a null value to be less than
162      * any nonnull value, and equal to any other null value.  Two nonnull
163      * values will be evaluated with the given comparator.
164      *
165      * @param <E>  the object type to compare
166      * @param comparator the comparator that wants to allow nulls
167      * @return  a version of that comparator that allows nulls
168      * @see NullComparator
169      */
170     @SuppressWarnings("unchecked")
171     public static <E> Comparator<E> nullLowComparator(Comparator<E> comparator) {
172         if (comparator == null) {
173             comparator = NATURAL_COMPARATOR;
174         }
175         return new NullComparator<E>(comparator, false);
176     }
177 
178     /**
179      * Gets a Comparator that controls the comparison of <code>null</code> values.
180      * <p>
181      * The returned comparator will consider a null value to be greater than
182      * any nonnull value, and equal to any other null value.  Two nonnull
183      * values will be evaluated with the given comparator.
184      *
185      * @param <E>  the object type to compare
186      * @param comparator the comparator that wants to allow nulls
187      * @return  a version of that comparator that allows nulls
188      * @see NullComparator
189      */
190     @SuppressWarnings("unchecked")
191     public static <E> Comparator<E> nullHighComparator(Comparator<E> comparator) {
192         if (comparator == null) {
193             comparator = NATURAL_COMPARATOR;
194         }
195         return new NullComparator<E>(comparator, true);
196     }
197 
198     /**
199      * Gets a Comparator that passes transformed objects to the given comparator.
200      * <p>
201      * Objects passed to the returned comparator will first be transformed
202      * by the given transformer before they are compared by the given
203      * comparator.
204      *
205      * @param <E>  the object type to compare
206      * @param comparator  the sort order to use
207      * @param transformer  the transformer to use
208      * @return  a comparator that transforms its input objects before comparing them
209      * @see  TransformingComparator
210      */
211     @SuppressWarnings("unchecked")
212     public static <E> Comparator<E> transformedComparator(Comparator<E> comparator,
213             final Transformer<? super E, ? extends E> transformer) {
214 
215         if (comparator == null) {
216             comparator = NATURAL_COMPARATOR;
217         }
218         return new TransformingComparator<E>(transformer, comparator);
219     }
220 
221     /**
222      * Returns the smaller of the given objects according to the given 
223      * comparator, returning the second object if the comparator
224      * returns equal.
225      *
226      * @param <E>  the object type to compare
227      * @param o1  the first object to compare
228      * @param o2  the second object to compare
229      * @param comparator  the sort order to use
230      * @return  the smaller of the two objects
231      */
232     @SuppressWarnings("unchecked")
233     public static <E> E min(final E o1, final E o2, Comparator<E> comparator) {
234         if (comparator == null) {
235             comparator = NATURAL_COMPARATOR;
236         }
237         final int c = comparator.compare(o1, o2);
238         return c < 0 ? o1 : o2;
239     }
240 
241     /**
242      * Returns the larger of the given objects according to the given 
243      * comparator, returning the second object if the comparator 
244      * returns equal.
245      *
246      * @param <E>  the object type to compare
247      * @param o1  the first object to compare
248      * @param o2  the second object to compare
249      * @param comparator  the sort order to use
250      * @return  the larger of the two objects
251      */
252     @SuppressWarnings("unchecked")
253     public static <E> E max(final E o1, final E o2, Comparator<E> comparator) {
254         if (comparator == null) {
255             comparator = NATURAL_COMPARATOR;
256         }
257         final int c = comparator.compare(o1, o2);
258         return c > 0 ? o1 : o2;
259     }
260     
261 }