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 }