1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.collections15.comparators;
17
18 import net.sf.collections15.Transformer;
19
20 import java.util.Comparator;
21
22
23 /***
24 * Decorates another <code>Comparator</code> with transformation behavior. That
25 * is, the input values are transformed, and the results are passed to the
26 * underlying <code>Comparator</code>'s. {@link Comparator#compare(Object,Object)
27 * compare} method.
28 *
29 * @see net.sf.collections15.Transformer
30 * @see ComparableComparator
31 * @author Chris Lambrou (port to Java 5.0)
32 * @since Collections15 1.0
33 */
34 public class TransformingComparator <I, O> implements Comparator<I>
35 {
36
37 /***
38 * The decorated <code>Comparator</code>.
39 */
40 protected Comparator<O> decorated;
41
42 /***
43 * The <code>Transformer</code> being used.
44 */
45 protected Transformer<I, O> transformer;
46
47 /***
48 * Returns an instance whose ordering is based on the natural ordering of
49 * the output of the specified <code>Transformer</code>.
50 *
51 * @param transformer The <code>Transformer</code> used to transform the
52 * compared objects prior to applying the natural sorting
53 * order of the resulting transformed output.
54 */
55 public static <I, O extends Comparable> TransformingComparator<I, O> getInstance(Transformer<I, O> transformer)
56 {
57 return decorate(transformer, new ComparableComparator<O>());
58 }
59
60 /***
61 * Returns an instance whose ordering is determined by applying the odereing
62 * of the specified <code>Comparator</code> to the output of the specified
63 * <code>Transformer</code>.
64 *
65 * @param transformer The <code>Transformer</code> used to transform the
66 * compared objects.
67 * @param decorated The decorated <code>Comparator</code> that is applied
68 * to the transformed comparison objects.
69 */
70 public static <I, O> TransformingComparator<I, O> decorate(Transformer<I, O> transformer, Comparator<O> decorated)
71 {
72 return new TransformingComparator<I, O>(transformer, decorated);
73 }
74
75 /***
76 * Constructs an instance with the given <code>Transformer</code> and
77 * <code>Comparator</code>.
78 *
79 * @param transformer The <code>Transformer</code> used to transform the
80 * compared objects.
81 * @param decorated The decorated <code>Comparator</code> that is applied
82 * to the transformed comparison objects.
83 *
84 * @throws IllegalArgumentException If either argument is <code>null</code>.
85 */
86 protected TransformingComparator(Transformer<I, O> transformer, Comparator<O> decorated)
87 {
88 if (transformer == null) {
89 throw new IllegalArgumentException("null transformer");
90 }
91 if (decorated == null) {
92 throw new IllegalArgumentException("null decorated comparator");
93 }
94 this.decorated = decorated;
95 this.transformer = transformer;
96 }
97
98 /***
99 * Returns the result of comparing the values from the transform operation.
100 *
101 * @param obj1 The first object to transform then compare.
102 * @param obj2 The second object to transform then compare.
103 *
104 * @return A negative value if <code>obj1</code> is less than
105 * <code>obj2</code>. A positive value if <code>obj1</code> is
106 * greater than <code>obj2</code>. Zero if the two objects are
107 * equivalent with respect to the ordering.
108 */
109 public int compare(I obj1, I obj2)
110 {
111 O value1 = transformer.transform(obj1);
112 O value2 = transformer.transform(obj2);
113 return decorated.compare(value1, value2);
114 }
115
116 }
117