1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.collect.Lists.newArrayList;
21 import static com.google.common.testing.SerializableTester.reserialize;
22 import static com.google.common.testing.SerializableTester.reserializeAndAssert;
23 import static com.google.common.truth.Truth.assertThat;
24 import static java.util.Arrays.asList;
25
26 import com.google.common.annotations.GwtCompatible;
27 import com.google.common.annotations.GwtIncompatible;
28 import com.google.common.base.Function;
29 import com.google.common.base.Functions;
30 import com.google.common.collect.Ordering.ArbitraryOrdering;
31 import com.google.common.collect.Ordering.IncomparableValueException;
32 import com.google.common.collect.testing.Helpers;
33 import com.google.common.primitives.Ints;
34 import com.google.common.testing.EqualsTester;
35 import com.google.common.testing.NullPointerTester;
36
37 import junit.framework.TestCase;
38
39 import java.util.Arrays;
40 import java.util.Collections;
41 import java.util.Comparator;
42 import java.util.Iterator;
43 import java.util.List;
44 import java.util.Random;
45 import java.util.RandomAccess;
46
47 import javax.annotation.Nullable;
48
49
50
51
52
53
54 @GwtCompatible(emulated = true)
55 public class OrderingTest extends TestCase {
56
57
58 private final Ordering<Number> numberOrdering = new NumberOrdering();
59
60 public void testAllEqual() {
61 Ordering<Object> comparator = Ordering.allEqual();
62 assertSame(comparator, comparator.reverse());
63
64 assertEquals(comparator.compare(null, null), 0);
65 assertEquals(comparator.compare(new Object(), new Object()), 0);
66 assertEquals(comparator.compare("apples", "oranges"), 0);
67 assertSame(comparator, reserialize(comparator));
68 assertEquals("Ordering.allEqual()", comparator.toString());
69
70 List<String> strings = ImmutableList.of("b", "a", "d", "c");
71 assertEquals(strings, comparator.sortedCopy(strings));
72 assertEquals(strings, comparator.immutableSortedCopy(strings));
73 }
74
75 public void testNatural() {
76 Ordering<Integer> comparator = Ordering.natural();
77 Helpers.testComparator(comparator,
78 Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE);
79 try {
80 comparator.compare(1, null);
81 fail();
82 } catch (NullPointerException expected) {}
83 try {
84 comparator.compare(null, 2);
85 fail();
86 } catch (NullPointerException expected) {}
87 try {
88 comparator.compare(null, null);
89 fail();
90 } catch (NullPointerException expected) {}
91 assertSame(comparator, reserialize(comparator));
92 assertEquals("Ordering.natural()", comparator.toString());
93 }
94
95 public void testFrom() {
96 Ordering<String> caseInsensitiveOrdering
97 = Ordering.from(String.CASE_INSENSITIVE_ORDER);
98 assertEquals(0, caseInsensitiveOrdering.compare("A", "a"));
99 assertTrue(caseInsensitiveOrdering.compare("a", "B") < 0);
100 assertTrue(caseInsensitiveOrdering.compare("B", "a") > 0);
101
102 @SuppressWarnings("deprecation")
103 Ordering<String> orderingFromOrdering =
104 Ordering.from(Ordering.<String>natural());
105 new EqualsTester()
106 .addEqualityGroup(caseInsensitiveOrdering, Ordering.from(String.CASE_INSENSITIVE_ORDER))
107 .addEqualityGroup(orderingFromOrdering, Ordering.natural())
108 .testEquals();
109 }
110
111 public void testExplicit_none() {
112 Comparator<Integer> c
113 = Ordering.explicit(Collections.<Integer>emptyList());
114 try {
115 c.compare(0, 0);
116 fail();
117 } catch (IncomparableValueException expected) {
118 assertEquals(0, expected.value);
119 }
120 reserializeAndAssert(c);
121 }
122
123 public void testExplicit_one() {
124 Comparator<Integer> c = Ordering.explicit(0);
125 assertEquals(0, c.compare(0, 0));
126 try {
127 c.compare(0, 1);
128 fail();
129 } catch (IncomparableValueException expected) {
130 assertEquals(1, expected.value);
131 }
132 reserializeAndAssert(c);
133 assertEquals("Ordering.explicit([0])", c.toString());
134 }
135
136 public void testExplicit_two() {
137 Comparator<Integer> c = Ordering.explicit(42, 5);
138 assertEquals(0, c.compare(5, 5));
139 assertTrue(c.compare(5, 42) > 0);
140 assertTrue(c.compare(42, 5) < 0);
141 try {
142 c.compare(5, 666);
143 fail();
144 } catch (IncomparableValueException expected) {
145 assertEquals(666, expected.value);
146 }
147 new EqualsTester()
148 .addEqualityGroup(c, Ordering.explicit(42, 5))
149 .addEqualityGroup(Ordering.explicit(5, 42))
150 .addEqualityGroup(Ordering.explicit(42))
151 .testEquals();
152 reserializeAndAssert(c);
153 }
154
155 public void testExplicit_sortingExample() {
156 Comparator<Integer> c
157 = Ordering.explicit(2, 8, 6, 1, 7, 5, 3, 4, 0, 9);
158 List<Integer> list = Arrays.asList(0, 3, 5, 6, 7, 8, 9);
159 Collections.sort(list, c);
160 assertThat(list).has().exactly(8, 6, 7, 5, 3, 0, 9).inOrder();
161 reserializeAndAssert(c);
162 }
163
164 public void testExplicit_withDuplicates() {
165 try {
166 Ordering.explicit(1, 2, 3, 4, 2);
167 fail();
168 } catch (IllegalArgumentException expected) {
169 }
170 }
171
172
173
174 public void testArbitrary_withoutCollisions() {
175 List<Object> list = Lists.newArrayList();
176 for (int i = 0; i < 50; i++) {
177 list.add(new Object());
178 }
179
180 Ordering<Object> arbitrary = Ordering.arbitrary();
181 Collections.sort(list, arbitrary);
182
183
184
185 Helpers.testComparator(arbitrary, list);
186
187 assertEquals("Ordering.arbitrary()", arbitrary.toString());
188 }
189
190 public void testArbitrary_withCollisions() {
191 List<Integer> list = Lists.newArrayList();
192 for (int i = 0; i < 50; i++) {
193 list.add(i);
194 }
195
196 Ordering<Object> arbitrary = new ArbitraryOrdering() {
197 @Override int identityHashCode(Object object) {
198 return ((Integer) object) % 5;
199 }
200 };
201
202
203 list = shuffledCopy(list, new Random(1));
204
205 Collections.sort(list, arbitrary);
206
207
208
209 Helpers.testComparator(arbitrary, list);
210 }
211
212 public void testUsingToString() {
213 Ordering<Object> ordering = Ordering.usingToString();
214 Helpers.testComparator(ordering, 1, 12, 124, 2);
215 assertEquals("Ordering.usingToString()", ordering.toString());
216 assertSame(ordering, reserialize(ordering));
217 }
218
219
220 private enum CharAtFunction implements Function<String, Character> {
221 AT0(0),
222 AT1(1),
223 AT2(2),
224 AT3(3),
225 AT4(4),
226 AT5(5),
227 ;
228
229 final int index;
230 CharAtFunction(int index) {
231 this.index = index;
232 }
233 @Override
234 public Character apply(String string) {
235 return string.charAt(index);
236 }
237 }
238
239 private static Ordering<String> byCharAt(int index) {
240 return Ordering.natural().onResultOf(CharAtFunction.values()[index]);
241 }
242
243 public void testCompound_static() {
244 Comparator<String> comparator = Ordering.compound(ImmutableList.of(
245 byCharAt(0), byCharAt(1), byCharAt(2),
246 byCharAt(3), byCharAt(4), byCharAt(5)));
247 Helpers.testComparator(comparator, ImmutableList.of(
248 "applesauce",
249 "apricot",
250 "artichoke",
251 "banality",
252 "banana",
253 "banquet",
254 "tangelo",
255 "tangerine"));
256 reserializeAndAssert(comparator);
257 }
258
259 public void testCompound_instance() {
260 Comparator<String> comparator = byCharAt(1).compound(byCharAt(0));
261 Helpers.testComparator(comparator, ImmutableList.of(
262 "red",
263 "yellow",
264 "violet",
265 "blue",
266 "indigo",
267 "green",
268 "orange"));
269 }
270
271 public void testCompound_instance_generics() {
272 Ordering<Object> objects = Ordering.explicit((Object) 1);
273 Ordering<Number> numbers = Ordering.explicit((Number) 1);
274 Ordering<Integer> integers = Ordering.explicit(1);
275
276
277 Ordering<Number> a = numbers.compound(numbers);
278
279
280
281 Ordering<Number> b = numbers.compound(objects);
282 Ordering<Number> c = objects.compound(numbers);
283
284 Ordering<Integer> d = numbers.compound(integers);
285 Ordering<Integer> e = integers.compound(numbers);
286
287
288
289
290 Ordering<Number> f = numbers.compound(objects).compound(objects);
291 Ordering<Number> g = objects.compound(numbers).compound(objects);
292 Ordering<Number> h = objects.compound(objects).compound(numbers);
293
294 Ordering<Number> i = numbers.compound(objects.compound(objects));
295 Ordering<Number> j = objects.compound(numbers.compound(objects));
296 Ordering<Number> k = objects.compound(objects.compound(numbers));
297
298
299
300 Ordering<Integer> l = objects.compound(numbers);
301
302
303
304
305
306
307
308 }
309
310 public void testReverse() {
311 Ordering<Number> reverseOrder = numberOrdering.reverse();
312 Helpers.testComparator(reverseOrder,
313 Integer.MAX_VALUE, 1, 0, -1, Integer.MIN_VALUE);
314
315 new EqualsTester()
316 .addEqualityGroup(reverseOrder, numberOrdering.reverse())
317 .addEqualityGroup(Ordering.natural().reverse())
318 .addEqualityGroup(Collections.reverseOrder())
319 .testEquals();
320 }
321
322 public void testReverseOfReverseSameAsForward() {
323
324
325 assertSame(numberOrdering, numberOrdering.reverse().reverse());
326 }
327
328 private enum StringLengthFunction implements Function<String, Integer> {
329 StringLength;
330
331 @Override
332 public Integer apply(String string) {
333 return string.length();
334 }
335 }
336
337 private static final Ordering<Integer> DECREASING_INTEGER
338 = Ordering.natural().reverse();
339
340 public void testOnResultOf_natural() {
341 Comparator<String> comparator
342 = Ordering.natural().onResultOf(StringLengthFunction.StringLength);
343 assertTrue(comparator.compare("to", "be") == 0);
344 assertTrue(comparator.compare("or", "not") < 0);
345 assertTrue(comparator.compare("that", "to") > 0);
346
347 new EqualsTester()
348 .addEqualityGroup(
349 comparator,
350 Ordering.natural().onResultOf(StringLengthFunction.StringLength))
351 .addEqualityGroup(DECREASING_INTEGER)
352 .testEquals();
353 reserializeAndAssert(comparator);
354 assertEquals("Ordering.natural().onResultOf(StringLength)",
355 comparator.toString());
356 }
357
358 public void testOnResultOf_chained() {
359 Comparator<String> comparator = DECREASING_INTEGER.onResultOf(
360 StringLengthFunction.StringLength);
361 assertTrue(comparator.compare("to", "be") == 0);
362 assertTrue(comparator.compare("not", "or") < 0);
363 assertTrue(comparator.compare("to", "that") > 0);
364
365 new EqualsTester()
366 .addEqualityGroup(
367 comparator,
368 DECREASING_INTEGER.onResultOf(StringLengthFunction.StringLength))
369 .addEqualityGroup(
370 DECREASING_INTEGER.onResultOf(Functions.constant(1)))
371 .addEqualityGroup(Ordering.natural())
372 .testEquals();
373 reserializeAndAssert(comparator);
374 assertEquals("Ordering.natural().reverse().onResultOf(StringLength)",
375 comparator.toString());
376 }
377
378 @SuppressWarnings("unchecked")
379 public void testLexicographical() {
380 Ordering<String> ordering = Ordering.natural();
381 Ordering<Iterable<String>> lexy = ordering.lexicographical();
382
383 ImmutableList<String> empty = ImmutableList.of();
384 ImmutableList<String> a = ImmutableList.of("a");
385 ImmutableList<String> aa = ImmutableList.of("a", "a");
386 ImmutableList<String> ab = ImmutableList.of("a", "b");
387 ImmutableList<String> b = ImmutableList.of("b");
388
389 Helpers.testComparator(lexy, empty, a, aa, ab, b);
390
391 new EqualsTester()
392 .addEqualityGroup(lexy, ordering.lexicographical())
393 .addEqualityGroup(numberOrdering.lexicographical())
394 .addEqualityGroup(Ordering.natural())
395 .testEquals();
396 }
397
398 public void testNullsFirst() {
399 Ordering<Integer> ordering = Ordering.natural().nullsFirst();
400 Helpers.testComparator(ordering, null, Integer.MIN_VALUE, 0, 1);
401
402 new EqualsTester()
403 .addEqualityGroup(ordering, Ordering.natural().nullsFirst())
404 .addEqualityGroup(numberOrdering.nullsFirst())
405 .addEqualityGroup(Ordering.natural())
406 .testEquals();
407 }
408
409 public void testNullsLast() {
410 Ordering<Integer> ordering = Ordering.natural().nullsLast();
411 Helpers.testComparator(ordering, 0, 1, Integer.MAX_VALUE, null);
412
413 new EqualsTester()
414 .addEqualityGroup(ordering, Ordering.natural().nullsLast())
415 .addEqualityGroup(numberOrdering.nullsLast())
416 .addEqualityGroup(Ordering.natural())
417 .testEquals();
418 }
419
420 public void testBinarySearch() {
421 List<Integer> ints = Lists.newArrayList(0, 2, 3, 5, 7, 9);
422 assertEquals(4, numberOrdering.binarySearch(ints, 7));
423 }
424
425 public void testSortedCopy() {
426 List<Integer> unsortedInts = Collections.unmodifiableList(
427 Arrays.asList(5, 0, 3, null, 0, 9));
428 List<Integer> sortedInts =
429 numberOrdering.nullsLast().sortedCopy(unsortedInts);
430 assertEquals(Arrays.asList(0, 0, 3, 5, 9, null), sortedInts);
431
432 assertEquals(Collections.emptyList(),
433 numberOrdering.sortedCopy(Collections.<Integer>emptyList()));
434 }
435
436 public void testImmutableSortedCopy() {
437 ImmutableList<Integer> unsortedInts = ImmutableList.of(5, 3, 0, 9, 3);
438 ImmutableList<Integer> sortedInts
439 = numberOrdering.immutableSortedCopy(unsortedInts);
440 assertEquals(Arrays.asList(0, 3, 3, 5, 9), sortedInts);
441
442 assertEquals(Collections.<Integer>emptyList(),
443 numberOrdering.immutableSortedCopy(Collections.<Integer>emptyList()));
444
445 List<Integer> listWithNull = Arrays.asList(5, 3, null, 9);
446 try {
447 Ordering.natural().nullsFirst().immutableSortedCopy(listWithNull);
448 fail();
449 } catch (NullPointerException expected) {
450 }
451 }
452
453 public void testIsOrdered() {
454 assertFalse(numberOrdering.isOrdered(asList(5, 3, 0, 9)));
455 assertFalse(numberOrdering.isOrdered(asList(0, 5, 3, 9)));
456 assertTrue(numberOrdering.isOrdered(asList(0, 3, 5, 9)));
457 assertTrue(numberOrdering.isOrdered(asList(0, 0, 3, 3)));
458 assertTrue(numberOrdering.isOrdered(asList(0, 3)));
459 assertTrue(numberOrdering.isOrdered(Collections.singleton(1)));
460 assertTrue(numberOrdering.isOrdered(Collections.<Integer>emptyList()));
461 }
462
463 public void testIsStrictlyOrdered() {
464 assertFalse(numberOrdering.isStrictlyOrdered(asList(5, 3, 0, 9)));
465 assertFalse(numberOrdering.isStrictlyOrdered(asList(0, 5, 3, 9)));
466 assertTrue(numberOrdering.isStrictlyOrdered(asList(0, 3, 5, 9)));
467 assertFalse(numberOrdering.isStrictlyOrdered(asList(0, 0, 3, 3)));
468 assertTrue(numberOrdering.isStrictlyOrdered(asList(0, 3)));
469 assertTrue(numberOrdering.isStrictlyOrdered(Collections.singleton(1)));
470 assertTrue(numberOrdering.isStrictlyOrdered(
471 Collections.<Integer>emptyList()));
472 }
473
474 public void testLeastOfIterable_empty_0() {
475 List<Integer> result = numberOrdering.leastOf(Arrays.<Integer>asList(), 0);
476 assertTrue(result instanceof RandomAccess);
477 assertListImmutable(result);
478 assertEquals(ImmutableList.<Integer>of(), result);
479 }
480
481 public void testLeastOfIterator_empty_0() {
482 List<Integer> result = numberOrdering.leastOf(
483 Iterators.<Integer>emptyIterator(), 0);
484 assertTrue(result instanceof RandomAccess);
485 assertListImmutable(result);
486 assertEquals(ImmutableList.<Integer>of(), result);
487 }
488
489 public void testLeastOfIterable_empty_1() {
490 List<Integer> result = numberOrdering.leastOf(Arrays.<Integer>asList(), 1);
491 assertTrue(result instanceof RandomAccess);
492 assertListImmutable(result);
493 assertEquals(ImmutableList.<Integer>of(), result);
494 }
495
496 public void testLeastOfIterator_empty_1() {
497 List<Integer> result = numberOrdering.leastOf(
498 Iterators.<Integer>emptyIterator(), 1);
499 assertTrue(result instanceof RandomAccess);
500 assertListImmutable(result);
501 assertEquals(ImmutableList.<Integer>of(), result);
502 }
503
504 public void testLeastOfIterable_simple_negativeOne() {
505 try {
506 numberOrdering.leastOf(Arrays.asList(3, 4, 5, -1), -1);
507 fail();
508 } catch (IllegalArgumentException expected) {
509 }
510 }
511
512 public void testLeastOfIterator_simple_negativeOne() {
513 try {
514 numberOrdering.leastOf(Iterators.forArray(3, 4, 5, -1), -1);
515 fail();
516 } catch (IllegalArgumentException expected) {
517 }
518 }
519
520 public void testLeastOfIterable_singleton_0() {
521 List<Integer> result = numberOrdering.leastOf(Arrays.asList(3), 0);
522 assertTrue(result instanceof RandomAccess);
523 assertListImmutable(result);
524 assertEquals(ImmutableList.<Integer>of(), result);
525 }
526
527 public void testLeastOfIterator_singleton_0() {
528 List<Integer> result = numberOrdering.leastOf(
529 Iterators.singletonIterator(3), 0);
530 assertTrue(result instanceof RandomAccess);
531 assertListImmutable(result);
532 assertEquals(ImmutableList.<Integer>of(), result);
533 }
534
535 public void testLeastOfIterable_simple_0() {
536 List<Integer> result = numberOrdering.leastOf(Arrays.asList(3, 4, 5, -1), 0);
537 assertTrue(result instanceof RandomAccess);
538 assertListImmutable(result);
539 assertEquals(ImmutableList.<Integer>of(), result);
540 }
541
542 public void testLeastOfIterator_simple_0() {
543 List<Integer> result = numberOrdering.leastOf(
544 Iterators.forArray(3, 4, 5, -1), 0);
545 assertTrue(result instanceof RandomAccess);
546 assertListImmutable(result);
547 assertEquals(ImmutableList.<Integer>of(), result);
548 }
549
550 public void testLeastOfIterable_simple_1() {
551 List<Integer> result = numberOrdering.leastOf(Arrays.asList(3, 4, 5, -1), 1);
552 assertTrue(result instanceof RandomAccess);
553 assertListImmutable(result);
554 assertEquals(ImmutableList.of(-1), result);
555 }
556
557 public void testLeastOfIterator_simple_1() {
558 List<Integer> result = numberOrdering.leastOf(
559 Iterators.forArray(3, 4, 5, -1), 1);
560 assertTrue(result instanceof RandomAccess);
561 assertListImmutable(result);
562 assertEquals(ImmutableList.of(-1), result);
563 }
564
565 public void testLeastOfIterable_simple_nMinusOne_withNullElement() {
566 List<Integer> list = Arrays.asList(3, null, 5, -1);
567 List<Integer> result = Ordering.natural().nullsLast().leastOf(list, list.size() - 1);
568 assertTrue(result instanceof RandomAccess);
569 assertListImmutable(result);
570 assertEquals(ImmutableList.of(-1, 3, 5), result);
571 }
572
573 public void testLeastOfIterator_simple_nMinusOne_withNullElement() {
574 Iterator<Integer> itr = Iterators.forArray(3, null, 5, -1);
575 List<Integer> result = Ordering.natural().nullsLast().leastOf(itr, 3);
576 assertTrue(result instanceof RandomAccess);
577 assertListImmutable(result);
578 assertEquals(ImmutableList.of(-1, 3, 5), result);
579 }
580
581 public void testLeastOfIterable_simple_nMinusOne() {
582 List<Integer> list = Arrays.asList(3, 4, 5, -1);
583 List<Integer> result = numberOrdering.leastOf(list, list.size() - 1);
584 assertTrue(result instanceof RandomAccess);
585 assertListImmutable(result);
586 assertEquals(ImmutableList.of(-1, 3, 4), result);
587 }
588
589 public void testLeastOfIterator_simple_nMinusOne() {
590 List<Integer> list = Arrays.asList(3, 4, 5, -1);
591 List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size() - 1);
592 assertTrue(result instanceof RandomAccess);
593 assertListImmutable(result);
594 assertEquals(ImmutableList.of(-1, 3, 4), result);
595 }
596
597 public void testLeastOfIterable_simple_n() {
598 List<Integer> list = Arrays.asList(3, 4, 5, -1);
599 List<Integer> result = numberOrdering.leastOf(list, list.size());
600 assertTrue(result instanceof RandomAccess);
601 assertListImmutable(result);
602 assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
603 }
604
605 public void testLeastOfIterator_simple_n() {
606 List<Integer> list = Arrays.asList(3, 4, 5, -1);
607 List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size());
608 assertTrue(result instanceof RandomAccess);
609 assertListImmutable(result);
610 assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
611 }
612
613 public void testLeastOfIterable_simple_n_withNullElement() {
614 List<Integer> list = Arrays.asList(3, 4, 5, null, -1);
615 List<Integer> result = Ordering.natural().nullsLast().leastOf(list, list.size());
616 assertTrue(result instanceof RandomAccess);
617 assertListImmutable(result);
618 assertEquals(Arrays.asList(-1, 3, 4, 5, null), result);
619 }
620
621 public void testLeastOfIterator_simple_n_withNullElement() {
622 List<Integer> list = Arrays.asList(3, 4, 5, null, -1);
623 List<Integer> result = Ordering.natural().nullsLast().leastOf(
624 list.iterator(), list.size());
625 assertTrue(result instanceof RandomAccess);
626 assertListImmutable(result);
627 assertEquals(Arrays.asList(-1, 3, 4, 5, null), result);
628 }
629
630 public void testLeastOfIterable_simple_nPlusOne() {
631 List<Integer> list = Arrays.asList(3, 4, 5, -1);
632 List<Integer> result = numberOrdering.leastOf(list, list.size() + 1);
633 assertTrue(result instanceof RandomAccess);
634 assertListImmutable(result);
635 assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
636 }
637
638 public void testLeastOfIterator_simple_nPlusOne() {
639 List<Integer> list = Arrays.asList(3, 4, 5, -1);
640 List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size() + 1);
641 assertTrue(result instanceof RandomAccess);
642 assertListImmutable(result);
643 assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
644 }
645
646 public void testLeastOfIterable_ties() {
647 Integer foo = new Integer(Integer.MAX_VALUE - 10);
648 Integer bar = new Integer(Integer.MAX_VALUE - 10);
649
650 assertNotSame(foo, bar);
651 assertEquals(foo, bar);
652
653 List<Integer> list = Arrays.asList(3, foo, bar, -1);
654 List<Integer> result = numberOrdering.leastOf(list, list.size());
655 assertEquals(ImmutableList.of(-1, 3, foo, bar), result);
656 }
657
658 public void testLeastOfIterator_ties() {
659 Integer foo = new Integer(Integer.MAX_VALUE - 10);
660 Integer bar = new Integer(Integer.MAX_VALUE - 10);
661
662 assertNotSame(foo, bar);
663 assertEquals(foo, bar);
664
665 List<Integer> list = Arrays.asList(3, foo, bar, -1);
666 List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size());
667 assertEquals(ImmutableList.of(-1, 3, foo, bar), result);
668 }
669
670 @GwtIncompatible("slow")
671 public void testLeastOf_reconcileAgainstSortAndSublist() {
672 runLeastOfComparison(1000, 300, 20);
673 }
674
675 public void testLeastOf_reconcileAgainstSortAndSublistSmall() {
676 runLeastOfComparison(10, 30, 2);
677 }
678
679 private static void runLeastOfComparison(
680 int iterations, int elements, int seeds) {
681 Random random = new Random(42);
682 Ordering<Integer> ordering = Ordering.natural();
683
684 for (int i = 0; i < iterations; i++) {
685 List<Integer> list = Lists.newArrayList();
686 for (int j = 0; j < elements; j++) {
687 list.add(random.nextInt(10 * i + j + 1));
688 }
689
690 for (int seed = 1; seed < seeds; seed++) {
691 int k = random.nextInt(10 * seed);
692 assertEquals(ordering.sortedCopy(list).subList(0, k),
693 ordering.leastOf(list, k));
694 }
695 }
696 }
697
698 public void testLeastOfIterableLargeK() {
699 List<Integer> list = Arrays.asList(4, 2, 3, 5, 1);
700 assertEquals(Arrays.asList(1, 2, 3, 4, 5), Ordering.natural()
701 .leastOf(list, Integer.MAX_VALUE));
702 }
703
704 public void testLeastOfIteratorLargeK() {
705 List<Integer> list = Arrays.asList(4, 2, 3, 5, 1);
706 assertEquals(Arrays.asList(1, 2, 3, 4, 5), Ordering.natural()
707 .leastOf(list.iterator(), Integer.MAX_VALUE));
708 }
709
710 public void testGreatestOfIterable_simple() {
711
712
713
714
715
716 List<Integer> list = Arrays.asList(3, 1, 3, 2, 4, 2, 4, 3);
717 assertEquals(Arrays.asList(4, 4, 3, 3), numberOrdering.greatestOf(list, 4));
718 }
719
720 public void testGreatestOfIterator_simple() {
721
722
723
724
725
726 List<Integer> list = Arrays.asList(3, 1, 3, 2, 4, 2, 4, 3);
727 assertEquals(Arrays.asList(4, 4, 3, 3),
728 numberOrdering.greatestOf(list.iterator(), 4));
729 }
730
731 private static void assertListImmutable(List<Integer> result) {
732 try {
733 result.set(0, 1);
734 fail();
735 } catch (UnsupportedOperationException expected) {
736
737 }
738 }
739
740 public void testIteratorMinAndMax() {
741 List<Integer> ints = Lists.newArrayList(5, 3, 0, 9);
742 assertEquals(9, (int) numberOrdering.max(ints.iterator()));
743 assertEquals(0, (int) numberOrdering.min(ints.iterator()));
744
745
746 Integer a = new Integer(4);
747 Integer b = new Integer(4);
748 ints = Lists.newArrayList(a, b, b);
749 assertSame(a, numberOrdering.max(ints.iterator()));
750 assertSame(a, numberOrdering.min(ints.iterator()));
751 }
752
753 public void testIteratorMinExhaustsIterator() {
754 List<Integer> ints = Lists.newArrayList(9, 0, 3, 5);
755 Iterator<Integer> iterator = ints.iterator();
756 assertEquals(0, (int) numberOrdering.min(iterator));
757 assertFalse(iterator.hasNext());
758 }
759
760 public void testIteratorMaxExhaustsIterator() {
761 List<Integer> ints = Lists.newArrayList(9, 0, 3, 5);
762 Iterator<Integer> iterator = ints.iterator();
763 assertEquals(9, (int) numberOrdering.max(iterator));
764 assertFalse(iterator.hasNext());
765 }
766
767 public void testIterableMinAndMax() {
768 List<Integer> ints = Lists.newArrayList(5, 3, 0, 9);
769 assertEquals(9, (int) numberOrdering.max(ints));
770 assertEquals(0, (int) numberOrdering.min(ints));
771
772
773 Integer a = new Integer(4);
774 Integer b = new Integer(4);
775 ints = Lists.newArrayList(a, b, b);
776 assertSame(a, numberOrdering.max(ints));
777 assertSame(a, numberOrdering.min(ints));
778 }
779
780 public void testVarargsMinAndMax() {
781
782
783 assertEquals(9, (int) numberOrdering.max(9, 3, 0, 5, 8));
784 assertEquals(9, (int) numberOrdering.max(5, 9, 0, 3, 8));
785 assertEquals(9, (int) numberOrdering.max(5, 3, 9, 0, 8));
786 assertEquals(9, (int) numberOrdering.max(5, 3, 0, 9, 8));
787 assertEquals(9, (int) numberOrdering.max(5, 3, 0, 8, 9));
788 assertEquals(0, (int) numberOrdering.min(0, 3, 5, 9, 8));
789 assertEquals(0, (int) numberOrdering.min(5, 0, 3, 9, 8));
790 assertEquals(0, (int) numberOrdering.min(5, 3, 0, 9, 8));
791 assertEquals(0, (int) numberOrdering.min(5, 3, 9, 0, 8));
792 assertEquals(0, (int) numberOrdering.min(5, 3, 0, 9, 0));
793
794
795 Integer a = new Integer(4);
796 Integer b = new Integer(4);
797 assertSame(a, numberOrdering.max(a, b, b));
798 assertSame(a, numberOrdering.min(a, b, b));
799 }
800
801 public void testParameterMinAndMax() {
802 assertEquals(5, (int) numberOrdering.max(3, 5));
803 assertEquals(5, (int) numberOrdering.max(5, 3));
804 assertEquals(3, (int) numberOrdering.min(3, 5));
805 assertEquals(3, (int) numberOrdering.min(5, 3));
806
807
808 Integer a = new Integer(4);
809 Integer b = new Integer(4);
810 assertSame(a, numberOrdering.max(a, b));
811 assertSame(a, numberOrdering.min(a, b));
812 }
813
814 private static class NumberOrdering extends Ordering<Number> {
815 @Override public int compare(Number a, Number b) {
816 return ((Double) a.doubleValue()).compareTo(b.doubleValue());
817 }
818 @Override public int hashCode() {
819 return NumberOrdering.class.hashCode();
820 }
821 @Override public boolean equals(Object other) {
822 return other instanceof NumberOrdering;
823 }
824 private static final long serialVersionUID = 0;
825 }
826
827
828
829
830
831
832
833
834 private static final int RECURSE_DEPTH = 2;
835
836 public void testCombinationsExhaustively_startingFromNatural() {
837 testExhaustively(Ordering.<String>natural(), "a", "b", "d");
838 }
839
840 @GwtIncompatible("too slow")
841 public void testCombinationsExhaustively_startingFromExplicit() {
842 testExhaustively(Ordering.explicit("a", "b", "c", "d"),
843 "a", "b", "d");
844 }
845
846 @GwtIncompatible("too slow")
847 public void testCombinationsExhaustively_startingFromUsingToString() {
848 testExhaustively(Ordering.usingToString(), 1, 12, 2);
849 }
850
851 @GwtIncompatible("too slow")
852 public void testCombinationsExhaustively_startingFromFromComparator() {
853 testExhaustively(Ordering.from(String.CASE_INSENSITIVE_ORDER),
854 "A", "b", "C", "d");
855 }
856
857 @GwtIncompatible("too slow")
858 public void testCombinationsExhaustively_startingFromArbitrary() {
859 Ordering<Object> arbitrary = Ordering.arbitrary();
860 Object[] array = {1, "foo", new Object()};
861
862
863 Arrays.sort(array, arbitrary);
864 testExhaustively(arbitrary, array);
865 }
866
867
868
869
870
871 private static <T> void testExhaustively(
872 Ordering<? super T> ordering, T... strictlyOrderedElements) {
873 checkArgument(strictlyOrderedElements.length >= 3, "strictlyOrderedElements "
874 + "requires at least 3 elements");
875 List<T> list = Arrays.asList(strictlyOrderedElements);
876
877
878 T[] emptyArray = Platform.newArray(strictlyOrderedElements, 0);
879
880
881 @SuppressWarnings("unchecked")
882 Scenario<T> starter = new Scenario<T>((Ordering) ordering, list, emptyArray);
883 verifyScenario(starter, 0);
884 }
885
886 private static <T> void verifyScenario(Scenario<T> scenario, int level) {
887 scenario.testCompareTo();
888 scenario.testIsOrdered();
889 scenario.testMinAndMax();
890 scenario.testBinarySearch();
891 scenario.testSortedCopy();
892
893 if (level < RECURSE_DEPTH) {
894 for (OrderingMutation alteration : OrderingMutation.values()) {
895 verifyScenario(alteration.mutate(scenario), level + 1);
896 }
897 }
898 }
899
900
901
902
903
904 private static class Scenario<T> {
905 final Ordering<T> ordering;
906 final List<T> strictlyOrderedList;
907 final T[] emptyArray;
908
909 Scenario(Ordering<T> ordering, List<T> strictlyOrderedList, T[] emptyArray) {
910 this.ordering = ordering;
911 this.strictlyOrderedList = strictlyOrderedList;
912 this.emptyArray = emptyArray;
913 }
914
915 void testCompareTo() {
916 Helpers.testComparator(ordering, strictlyOrderedList);
917 }
918
919 void testIsOrdered() {
920 assertTrue(ordering.isOrdered(strictlyOrderedList));
921 assertTrue(ordering.isStrictlyOrdered(strictlyOrderedList));
922 }
923
924 @SuppressWarnings("unchecked")
925 void testMinAndMax() {
926 List<T> shuffledList = Lists.newArrayList(strictlyOrderedList);
927 shuffledList = shuffledCopy(shuffledList, new Random(5));
928
929 T min = strictlyOrderedList.get(0);
930 T max = strictlyOrderedList.get(strictlyOrderedList.size() - 1);
931
932 T first = shuffledList.get(0);
933 T second = shuffledList.get(1);
934 T third = shuffledList.get(2);
935 T[] rest = shuffledList.subList(3, shuffledList.size()).toArray(emptyArray);
936
937 assertEquals(min, ordering.min(shuffledList));
938 assertEquals(min, ordering.min(shuffledList.iterator()));
939 assertEquals(min, ordering.min(first, second, third, rest));
940 assertEquals(min, ordering.min(min, max));
941 assertEquals(min, ordering.min(max, min));
942
943 assertEquals(max, ordering.max(shuffledList));
944 assertEquals(max, ordering.max(shuffledList.iterator()));
945 assertEquals(max, ordering.max(first, second, third, rest));
946 assertEquals(max, ordering.max(min, max));
947 assertEquals(max, ordering.max(max, min));
948 }
949
950 void testBinarySearch() {
951 for (int i = 0; i < strictlyOrderedList.size(); i++) {
952 assertEquals(i, ordering.binarySearch(
953 strictlyOrderedList, strictlyOrderedList.get(i)));
954 }
955 List<T> newList = Lists.newArrayList(strictlyOrderedList);
956 T valueNotInList = newList.remove(1);
957 assertEquals(-2, ordering.binarySearch(newList, valueNotInList));
958 }
959
960 void testSortedCopy() {
961 List<T> shuffledList = Lists.newArrayList(strictlyOrderedList);
962 shuffledList = shuffledCopy(shuffledList, new Random(5));
963
964 assertEquals(strictlyOrderedList, ordering.sortedCopy(shuffledList));
965
966 if (!strictlyOrderedList.contains(null)) {
967 assertEquals(strictlyOrderedList, ordering.immutableSortedCopy(shuffledList));
968 }
969 }
970 }
971
972
973
974
975
976
977
978 private enum OrderingMutation {
979 REVERSE {
980 @Override <T> Scenario<?> mutate(Scenario<T> scenario) {
981 List<T> newList = Lists.newArrayList(scenario.strictlyOrderedList);
982 Collections.reverse(newList);
983 return new Scenario<T>(scenario.ordering.reverse(), newList, scenario.emptyArray);
984 }
985 },
986 NULLS_FIRST {
987 @Override <T> Scenario<?> mutate(Scenario<T> scenario) {
988 @SuppressWarnings("unchecked")
989 List<T> newList = Lists.newArrayList((T) null);
990 for (T t : scenario.strictlyOrderedList) {
991 if (t != null) {
992 newList.add(t);
993 }
994 }
995 return new Scenario<T>(scenario.ordering.nullsFirst(), newList, scenario.emptyArray);
996 }
997 },
998 NULLS_LAST {
999 @Override <T> Scenario<?> mutate(Scenario<T> scenario) {
1000 List<T> newList = Lists.newArrayList();
1001 for (T t : scenario.strictlyOrderedList) {
1002 if (t != null) {
1003 newList.add(t);
1004 }
1005 }
1006 newList.add(null);
1007 return new Scenario<T>(scenario.ordering.nullsLast(), newList, scenario.emptyArray);
1008 }
1009 },
1010 ON_RESULT_OF {
1011 @Override <T> Scenario<?> mutate(final Scenario<T> scenario) {
1012 Ordering<Integer> ordering = scenario.ordering.onResultOf(
1013 new Function<Integer, T>() {
1014 @Override
1015 public T apply(@Nullable Integer from) {
1016 return scenario.strictlyOrderedList.get(from);
1017 }
1018 });
1019 List<Integer> list = Lists.newArrayList();
1020 for (int i = 0; i < scenario.strictlyOrderedList.size(); i++) {
1021 list.add(i);
1022 }
1023 return new Scenario<Integer>(ordering, list, new Integer[0]);
1024 }
1025 },
1026 COMPOUND_THIS_WITH_NATURAL {
1027 @SuppressWarnings("unchecked")
1028 @Override <T> Scenario<?> mutate(Scenario<T> scenario) {
1029 List<Composite<T>> composites = Lists.newArrayList();
1030 for (T t : scenario.strictlyOrderedList) {
1031 composites.add(new Composite<T>(t, 1));
1032 composites.add(new Composite<T>(t, 2));
1033 }
1034 Ordering<Composite<T>> ordering =
1035 scenario.ordering.onResultOf(Composite.<T>getValueFunction())
1036 .compound(Ordering.natural());
1037 return new Scenario<Composite<T>>(ordering, composites, new Composite[0]);
1038 }
1039 },
1040 COMPOUND_NATURAL_WITH_THIS {
1041 @SuppressWarnings("unchecked")
1042 @Override <T> Scenario<?> mutate(Scenario<T> scenario) {
1043 List<Composite<T>> composites = Lists.newArrayList();
1044 for (T t : scenario.strictlyOrderedList) {
1045 composites.add(new Composite<T>(t, 1));
1046 }
1047 for (T t : scenario.strictlyOrderedList) {
1048 composites.add(new Composite<T>(t, 2));
1049 }
1050 Ordering<Composite<T>> ordering = Ordering.natural().compound(
1051 scenario.ordering.onResultOf(Composite.<T>getValueFunction()));
1052 return new Scenario<Composite<T>>(ordering, composites, new Composite[0]);
1053 }
1054 },
1055 LEXICOGRAPHICAL {
1056 @SuppressWarnings("unchecked")
1057 @Override <T> Scenario<?> mutate(Scenario<T> scenario) {
1058 List<Iterable<T>> words = Lists.newArrayList();
1059 words.add(Collections.<T>emptyList());
1060 for (T t : scenario.strictlyOrderedList) {
1061 words.add(Arrays.asList(t));
1062 for (T s : scenario.strictlyOrderedList) {
1063 words.add(Arrays.asList(t, s));
1064 }
1065 }
1066 return new Scenario<Iterable<T>>(
1067 scenario.ordering.lexicographical(), words, new Iterable[0]);
1068 }
1069 },
1070 ;
1071
1072 abstract <T> Scenario<?> mutate(Scenario<T> scenario);
1073 }
1074
1075
1076
1077
1078
1079 private static class Composite<T> implements Comparable<Composite<T>> {
1080 final T value;
1081 final int rank;
1082
1083 Composite(T value, int rank) {
1084 this.value = value;
1085 this.rank = rank;
1086 }
1087
1088
1089
1090 @Override
1091 public int compareTo(Composite<T> that) {
1092 return Ints.compare(rank, that.rank);
1093 }
1094
1095 static <T> Function<Composite<T>, T> getValueFunction() {
1096 return new Function<Composite<T>, T>() {
1097 @Override
1098 public T apply(Composite<T> from) {
1099 return from.value;
1100 }
1101 };
1102 }
1103 }
1104
1105 @GwtIncompatible("NullPointerTester")
1106 public void testNullPointerExceptions() {
1107 NullPointerTester tester = new NullPointerTester();
1108 tester.testAllPublicStaticMethods(Ordering.class);
1109
1110
1111 tester.testAllPublicInstanceMethods(Ordering.usingToString().nullsFirst());
1112 }
1113
1114 private static <T> List<T> shuffledCopy(List<T> in, Random random) {
1115 List<T> mutable = newArrayList(in);
1116 List<T> out = newArrayList();
1117 while (!mutable.isEmpty()) {
1118 out.add(mutable.remove(random.nextInt(mutable.size())));
1119 }
1120 return out;
1121 }
1122 }