1 /*
2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.util;
26
27 import java.io.Serializable;
28 import java.util.function.BinaryOperator;
29 import java.util.function.Function;
30 import java.util.function.ToDoubleFunction;
31 import java.util.function.ToIntFunction;
32 import java.util.function.ToLongFunction;
33
34 /**
35 * This class consists of {@code static} utility methods for comparators. Mostly
36 * factory method that returns a {@link Comparator}.
37 *
38 * <p> Unless otherwise noted, passing a {@code null} argument to a method in
39 * this class will cause a {@link NullPointerException} to be thrown.
40 *
41 * @see Comparator
42 * @since 1.8
43 */
44 public class Comparators {
45 private Comparators() {
46 throw new AssertionError("no instances");
47 }
48
49 /**
50 * Compares {@link Comparable} objects in natural order.
51 *
52 * @see Comparable
53 */
54 private enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
55 INSTANCE;
56
57 @Override
58 public int compare(Comparable<Object> c1, Comparable<Object> c2) {
59 return c1.compareTo(c2);
60 }
61 }
62
63 /**
64 * Returns a comparator that imposes the reverse of the <em>natural
65 * ordering</em>.
66 *
67 * <p>The returned comparator is serializable.
68 *
69 * @param <T> {@link Comparable} type
70 *
71 * @return A comparator that imposes the reverse of the <i>natural
72 * ordering</i> on a collection of objects that implement
73 * the {@link Comparable} interface.
74 * @see Comparable
75 */
76 public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
77 return Collections.reverseOrder();
78 }
79
80 /**
81 * Returns a comparator that imposes the reverse ordering of the specified
82 * {@link Comparator}.
83 *
84 * <p>The returned comparator is serializable (assuming the specified
85 * comparator is also serializable).
86 *
87 * @param <T> the element type to be compared
88 * @param cmp a comparator whose ordering is to be reversed by the returned
89 * comparator
90 * @return A comparator that imposes the reverse ordering of the
91 * specified comparator.
92 */
93 public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
94 Objects.requireNonNull(cmp);
95 return Collections.reverseOrder(cmp);
96 }
97
98 /**
99 * Gets a comparator compares {@link Comparable} type in natural order.
100 *
101 * @param <T> {@link Comparable} type
102 */
103 public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
104 return (Comparator<T>) NaturalOrderComparator.INSTANCE;
105 }
106
107 /**
108 * Gets a comparator compares {@link Map.Entry} in natural order on key.
109 *
110 * @param <K> {@link Comparable} key type
111 * @param <V> value type
112 */
113 public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> naturalOrderKeys() {
114 return (Comparator<Map.Entry<K, V>> & Serializable)
115 (c1, c2) -> c1.getKey().compareTo(c2.getKey());
116 }
117
118 /**
119 * Gets a comparator compares {@link Map.Entry} in natural order on value.
120 *
121 * @param <K> key type
122 * @param <V> {@link Comparable} value type
123 */
124 public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> naturalOrderValues() {
125 return (Comparator<Map.Entry<K, V>> & Serializable)
126 (c1, c2) -> c1.getValue().compareTo(c2.getValue());
127 }
128
129 /**
130 * Gets a comparator compares {@link Map.Entry} by key using the given
131 * {@link Comparator}.
132 *
133 * <p>The returned comparator is serializable assuming the specified
134 * comparators are also serializable.
135 *
136 * @param <K> key type
137 * @param <V> value type
138 * @param cmp the key {@link Comparator}
139 */
140 public static <K, V> Comparator<Map.Entry<K, V>> byKey(Comparator<? super K> cmp) {
141 Objects.requireNonNull(cmp);
142 return (Comparator<Map.Entry<K, V>> & Serializable)
143 (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
144 }
145
146 /**
147 * Gets a comparator compares {@link Map.Entry} by value using the given
148 * {@link Comparator}.
149 *
150 * @param <K> key type
151 * @param <V> value type
152 * @param cmp the value {@link Comparator}
153 */
154 public static <K, V> Comparator<Map.Entry<K, V>> byValue(Comparator<? super V> cmp) {
155 Objects.requireNonNull(cmp);
156 return (Comparator<Map.Entry<K, V>> & Serializable)
157 (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
158 }
159
160 /**
161 * Accepts a function that extracts a {@link java.lang.Comparable
162 * Comparable} sort key from a type {@code T}, and returns a {@code
163 * Comparator<T>} that compares by that sort key. For example, if a class
164 * {@code Person} has a {@code String}-valued getter {@code getLastName},
165 * then {@code comparing(Person::getLastName)} would return a {@code
166 * Comparator<Person>} that compares {@code Person} objects by their last
167 * name.
168 *
169 * @param <T> the original element type
170 * @param <U> the {@link Comparable} type for comparison
171 * @param keyExtractor the function used to extract the {@link Comparable} sort key
172 */
173 public static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor) {
174 Objects.requireNonNull(keyExtractor);
175 return (Comparator<T> & Serializable)
176 (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
177 }
178
179 /**
180 * Accepts a function that extracts an {@code int} value from a type {@code
181 * T}, and returns a {@code Comparator<T>} that compares by that value.
182 *
183 * <p>The returned comparator is serializable assuming the specified
184 * function is also serializable.
185 *
186 * @see #comparing(Function)
187 * @param <T> the original element type
188 * @param keyExtractor the function used to extract the integer value
189 */
190 public static <T> Comparator<T> comparing(ToIntFunction<? super T> keyExtractor) {
191 Objects.requireNonNull(keyExtractor);
192 return (Comparator<T> & Serializable)
193 (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
194 }
195
196 /**
197 * Accepts a function that extracts a {@code long} value from a type {@code
198 * T}, and returns a {@code Comparator<T>} that compares by that value.
199 *
200 * <p>The returned comparator is serializable assuming the specified
201 * function is also serializable.
202 *
203 * @see #comparing(Function)
204 * @param <T> the original element type
205 * @param keyExtractor the function used to extract the long value
206 */
207 public static <T> Comparator<T> comparing(ToLongFunction<? super T> keyExtractor) {
208 Objects.requireNonNull(keyExtractor);
209 return (Comparator<T> & Serializable)
210 (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
211 }
212
213 /**
214 * Accepts a function that extracts a {@code double} value from a type
215 * {@code T}, and returns a {@code Comparator<T>} that compares by that
216 * value.
217 *
218 * <p>The returned comparator is serializable assuming the specified
219 * function is also serializable.
220 *
221 * @see #comparing(Function)
222 * @param <T> the original element type
223 * @param keyExtractor the function used to extract the double value
224 */
225 public static<T> Comparator<T> comparing(ToDoubleFunction<? super T> keyExtractor) {
226 Objects.requireNonNull(keyExtractor);
227 return (Comparator<T> & Serializable)
228 (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
229 }
230
231 /**
232 * Constructs a lexicographic order from two {@link Comparator}s. For
233 * example, if you have comparators {@code byLastName} and {@code
234 * byFirstName}, each of type {@code Comparator<Person>}, then {@code
235 * compose(byLastName, byFirstName)} creates a {@code Comparator<Person>}
236 * which sorts by last name, and for equal last names sorts by first name.
237 *
238 * <p>The returned comparator is serializable assuming the specified
239 * comparators are also serializable.
240 *
241 * @param <T> the element type to be compared
242 * @param first the first comparator
243 * @param second the secondary comparator used when equals on the first
244 */
245 public static<T> Comparator<T> compose(Comparator<? super T> first, Comparator<? super T> second) {
246 Objects.requireNonNull(first);
247 Objects.requireNonNull(second);
248 return (Comparator<T> & Serializable) (c1, c2) -> {
249 int res = first.compare(c1, c2);
250 return (res != 0) ? res : second.compare(c1, c2);
251 };
252 }
253
254 /**
255 * Constructs a {@link BinaryOperator} which returns the lesser of two elements
256 * according to the specified {@code Comparator}
257 *
258 * @param comparator A {@code Comparator} for comparing the two values
259 * @param <T> the type of the elements to be compared
260 * @return a {@code BinaryOperator} which returns the lesser of its operands,
261 * according to the supplied {@code Comparator}
262 */
263 public static<T> BinaryOperator<T> lesserOf(Comparator<? super T> comparator) {
264 Objects.requireNonNull(comparator);
265 return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
266 }
267
268 /**
269 * Constructs a {@link BinaryOperator} which returns the greater of two elements
270 * according to the specified {@code Comparator}
271 *
272 * @param comparator A {@code Comparator} for comparing the two values
273 * @param <T> the type of the elements to be compared
274 * @return a {@code BinaryOperator} which returns the greater of its operands,
275 * according to the supplied {@code Comparator}
276 */
277 public static<T> BinaryOperator<T> greaterOf(Comparator<? super T> comparator) {
278 Objects.requireNonNull(comparator);
279 return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
280 }
281 }
|
1 /*
2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.util;
26
27 import java.io.Serializable;
28 import java.util.function.BinaryOperator;
29 import java.util.function.Function;
30 import java.util.function.ToDoubleFunction;
31 import java.util.function.ToIntFunction;
32 import java.util.function.ToLongFunction;
33
34 /**
35 * Package private supporting class for {@link Comparator}.
36 */
37 class Comparators {
38 private Comparators() {
39 throw new AssertionError("no instances");
40 }
41
42 /**
43 * Compares {@link Comparable} objects in natural order.
44 *
45 * @see Comparable
46 */
47 enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
48 INSTANCE;
49
50 @Override
51 public int compare(Comparable<Object> c1, Comparable<Object> c2) {
52 return c1.compareTo(c2);
53 }
54 }
55
56 /**
57 * Null-friendly comparators
58 */
59 static class NullComparator<T> implements Comparator<T>, Serializable {
60 private static final long serialVersionUID = -7569533591570686392L;
61 private final int sign;
62 private final Comparator<T> real;
63
64 NullComparator(int sign, Comparator<? super T> real) {
65 this.sign = sign;
66 this.real = (Comparator<T>) Objects.requireNonNull(real);
67 }
68
69 @Override
70 public int compare(T a, T b) {
71 if (a == null) {
72 return (b == null) ? 0 : sign;
73 } else if (b == null) {
74 return -sign;
75 } else {
76 return (real == null) ? 0 : real.compare(a, b);
77 }
78 }
79
80 @Override
81 public Comparator<T> thenComparing(Comparator<? super T> other) {
82 Objects.requireNonNull(other);
83 return new NullComparator(sign, real.thenComparing(other));
84 }
85
86 @Override
87 public Comparator<T> reversed() {
88 return new NullComparator(-sign, real.reversed());
89 }
90 }
91 }
|