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.comparators;
18
19 import java.io.Serializable;
20 import java.util.Comparator;
21
22 /**
23 * A {@link Comparator} for {@link Boolean} objects that can sort either
24 * true or false first.
25 * <p>
26 * @see #getTrueFirstComparator()
27 * @see #getFalseFirstComparator()
28 * @see #getBooleanComparator(boolean)
29 *
30 * @since Commons Collections 3.0
31 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
32 *
33 * @author Rodney Waldhoff
34 */
35 public final class BooleanComparator implements Comparator, Serializable {
36
37 /** Serialization version. */
38 private static final long serialVersionUID = 1830042991606340609L;
39
40 /** Constant "true first" reference. */
41 private static final BooleanComparator TRUE_FIRST = new BooleanComparator(true);
42
43 /** Constant "false first" reference. */
44 private static final BooleanComparator FALSE_FIRST = new BooleanComparator(false);
45
46 /** <code>true</code> iff <code>true</code> values sort before <code>false</code> values. */
47 private boolean trueFirst = false;
48
49 //-----------------------------------------------------------------------
50 /**
51 * Returns a BooleanComparator instance that sorts
52 * <code>true</code> values before <code>false</code> values.
53 * <p />
54 * Clients are encouraged to use the value returned from
55 * this method instead of constructing a new instance
56 * to reduce allocation and garbage collection overhead when
57 * multiple BooleanComparators may be used in the same
58 * virtual machine.
59 *
60 * @return the true first singleton BooleanComparator
61 */
62 public static BooleanComparator getTrueFirstComparator() {
63 return TRUE_FIRST;
64 }
65
66 /**
67 * Returns a BooleanComparator instance that sorts
68 * <code>false</code> values before <code>true</code> values.
69 * <p />
70 * Clients are encouraged to use the value returned from
71 * this method instead of constructing a new instance
72 * to reduce allocation and garbage collection overhead when
73 * multiple BooleanComparators may be used in the same
74 * virtual machine.
75 *
76 * @return the false first singleton BooleanComparator
77 */
78 public static BooleanComparator getFalseFirstComparator() {
79 return FALSE_FIRST;
80 }
81
82 /**
83 * Returns a BooleanComparator instance that sorts
84 * <code><i>trueFirst</i></code> values before
85 * <code>!<i>trueFirst</i></code> values.
86 * <p />
87 * Clients are encouraged to use the value returned from
88 * this method instead of constructing a new instance
89 * to reduce allocation and garbage collection overhead when
90 * multiple BooleanComparators may be used in the same
91 * virtual machine.
92 *
93 * @param trueFirst when <code>true</code>, sort
94 * <code>true</code> <code>Boolean</code>s before <code>false</code>
95 * @return a singleton BooleanComparator instance
96 */
97 public static BooleanComparator getBooleanComparator(boolean trueFirst) {
98 return trueFirst ? TRUE_FIRST : FALSE_FIRST;
99 }
100
101 //-----------------------------------------------------------------------
102 /**
103 * Creates a <code>BooleanComparator</code> that sorts
104 * <code>false</code> values before <code>true</code> values.
105 * <p>
106 * Equivalent to {@link #BooleanComparator(boolean) BooleanComparator(false)}.
107 * <p>
108 * Please use the static factory instead whenever possible.
109 */
110 public BooleanComparator() {
111 this(false);
112 }
113
114 /**
115 * Creates a <code>BooleanComparator</code> that sorts
116 * <code><i>trueFirst</i></code> values before
117 * <code>!<i>trueFirst</i></code> values.
118 * <p>
119 * Please use the static factories instead whenever possible.
120 *
121 * @param trueFirst when <code>true</code>, sort
122 * <code>true</code> boolean values before <code>false</code>
123 */
124 public BooleanComparator(boolean trueFirst) {
125 this.trueFirst = trueFirst;
126 }
127
128 //-----------------------------------------------------------------------
129 /**
130 * Compares two arbitrary Objects.
131 * When both arguments are <code>Boolean</code>, this method is equivalent to
132 * {@link #compare(Boolean,Boolean) compare((Boolean)<i>obj1</i>,(Boolean)<i>obj2</i>)}.
133 * When either argument is not a <code>Boolean</code>, this methods throws
134 * a {@link ClassCastException}.
135 *
136 * @param obj1 the first object to compare
137 * @param obj2 the second object to compare
138 * @return negative if obj1 is less, positive if greater, zero if equal
139 * @throws ClassCastException when either argument is not <code>Boolean</code>
140 */
141 public int compare(Object obj1, Object obj2) {
142 return compare((Boolean)obj1, (Boolean)obj2);
143 }
144
145 /**
146 * Compares two non-<code>null</code> <code>Boolean</code> objects
147 * according to the value of {@link #sortsTrueFirst()}.
148 *
149 * @param b1 the first boolean to compare
150 * @param b2 the second boolean to compare
151 * @return negative if obj1 is less, positive if greater, zero if equal
152 * @throws NullPointerException when either argument <code>null</code>
153 */
154 public int compare(Boolean b1, Boolean b2) {
155 boolean v1 = b1.booleanValue();
156 boolean v2 = b2.booleanValue();
157
158 return (v1 ^ v2) ? ( (v1 ^ trueFirst) ? 1 : -1 ) : 0;
159 }
160
161 //-----------------------------------------------------------------------
162 /**
163 * Implement a hash code for this comparator that is consistent with
164 * {@link #equals(Object) equals}.
165 *
166 * @return a hash code for this comparator.
167 */
168 public int hashCode() {
169 int hash = "BooleanComparator".hashCode();
170 return trueFirst ? -1 * hash : hash;
171 }
172
173 /**
174 * Returns <code>true</code> iff <i>that</i> Object is
175 * is a {@link Comparator} whose ordering is known to be
176 * equivalent to mine.
177 * <p>
178 * This implementation returns <code>true</code>
179 * iff <code><i>that</i></code> is a {@link BooleanComparator}
180 * whose value of {@link #sortsTrueFirst()} is equal to mine.
181 *
182 * @param object the object to compare to
183 * @return true if equal
184 */
185 public boolean equals(Object object) {
186 return (this == object) ||
187 ((object instanceof BooleanComparator) &&
188 (this.trueFirst == ((BooleanComparator)object).trueFirst));
189 }
190
191 //-----------------------------------------------------------------------
192 /**
193 * Returns <code>true</code> iff
194 * I sort <code>true</code> values before
195 * <code>false</code> values. In other words,
196 * returns <code>true</code> iff
197 * {@link #compare(Boolean,Boolean) compare(Boolean.FALSE,Boolean.TRUE)}
198 * returns a positive value.
199 *
200 * @return the trueFirst flag
201 */
202 public boolean sortsTrueFirst() {
203 return trueFirst;
204 }
205
206 }