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