001: /*
002: * Copyright 2003-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.collections.comparators;
017:
018: import java.io.Serializable;
019: import java.util.Comparator;
020:
021: /**
022: * A {@link Comparator} for {@link Boolean} objects that can sort either
023: * true or false first.
024: * <p>
025: * @see #getTrueFirstComparator()
026: * @see #getFalseFirstComparator()
027: * @see #getBooleanComparator(boolean)
028: *
029: * @since Commons Collections 3.0
030: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
031: *
032: * @author Rodney Waldhoff
033: */
034: public final class BooleanComparator implements Comparator,
035: Serializable {
036:
037: /** Serialization version. */
038: private static final long serialVersionUID = 1830042991606340609L;
039:
040: /** Constant "true first" reference. */
041: private static final BooleanComparator TRUE_FIRST = new BooleanComparator(
042: true);
043:
044: /** Constant "false first" reference. */
045: private static final BooleanComparator FALSE_FIRST = new BooleanComparator(
046: false);
047:
048: /** <code>true</code> iff <code>true</code> values sort before <code>false</code> values. */
049: private boolean trueFirst = false;
050:
051: //-----------------------------------------------------------------------
052: /**
053: * Returns a BooleanComparator instance that sorts
054: * <code>true</code> values before <code>false</code> values.
055: * <p />
056: * Clients are encouraged to use the value returned from
057: * this method instead of constructing a new instance
058: * to reduce allocation and garbage collection overhead when
059: * multiple BooleanComparators may be used in the same
060: * virtual machine.
061: *
062: * @return the true first singleton BooleanComparator
063: */
064: public static BooleanComparator getTrueFirstComparator() {
065: return TRUE_FIRST;
066: }
067:
068: /**
069: * Returns a BooleanComparator instance that sorts
070: * <code>false</code> values before <code>true</code> values.
071: * <p />
072: * Clients are encouraged to use the value returned from
073: * this method instead of constructing a new instance
074: * to reduce allocation and garbage collection overhead when
075: * multiple BooleanComparators may be used in the same
076: * virtual machine.
077: *
078: * @return the false first singleton BooleanComparator
079: */
080: public static BooleanComparator getFalseFirstComparator() {
081: return FALSE_FIRST;
082: }
083:
084: /**
085: * Returns a BooleanComparator instance that sorts
086: * <code><i>trueFirst</i></code> values before
087: * <code>!<i>trueFirst</i></code> values.
088: * <p />
089: * Clients are encouraged to use the value returned from
090: * this method instead of constructing a new instance
091: * to reduce allocation and garbage collection overhead when
092: * multiple BooleanComparators may be used in the same
093: * virtual machine.
094: *
095: * @param trueFirst when <code>true</code>, sort
096: * <code>true</code> <code>Boolean</code>s before <code>false</code>
097: * @return a singleton BooleanComparator instance
098: */
099: public static BooleanComparator getBooleanComparator(
100: boolean trueFirst) {
101: return trueFirst ? TRUE_FIRST : FALSE_FIRST;
102: }
103:
104: //-----------------------------------------------------------------------
105: /**
106: * Creates a <code>BooleanComparator</code> that sorts
107: * <code>false</code> values before <code>true</code> values.
108: * <p>
109: * Equivalent to {@link #BooleanComparator(boolean) BooleanComparator(false)}.
110: * <p>
111: * Please use the static factory instead whenever possible.
112: */
113: public BooleanComparator() {
114: this (false);
115: }
116:
117: /**
118: * Creates a <code>BooleanComparator</code> that sorts
119: * <code><i>trueFirst</i></code> values before
120: * <code>!<i>trueFirst</i></code> values.
121: * <p>
122: * Please use the static factories instead whenever possible.
123: *
124: * @param trueFirst when <code>true</code>, sort
125: * <code>true</code> boolean values before <code>false</code>
126: */
127: public BooleanComparator(boolean trueFirst) {
128: this .trueFirst = trueFirst;
129: }
130:
131: //-----------------------------------------------------------------------
132: /**
133: * Compares two arbitrary Objects.
134: * When both arguments are <code>Boolean</code>, this method is equivalent to
135: * {@link #compare(Boolean,Boolean) compare((Boolean)<i>obj1</i>,(Boolean)<i>obj2</i>)}.
136: * When either argument is not a <code>Boolean</code>, this methods throws
137: * a {@link ClassCastException}.
138: *
139: * @param obj1 the first object to compare
140: * @param obj2 the second object to compare
141: * @return negative if obj1 is less, positive if greater, zero if equal
142: * @throws ClassCastException when either argument is not <code>Boolean</code>
143: */
144: public int compare(Object obj1, Object obj2) {
145: return compare((Boolean) obj1, (Boolean) obj2);
146: }
147:
148: /**
149: * Compares two non-<code>null</code> <code>Boolean</code> objects
150: * according to the value of {@link #sortsTrueFirst()}.
151: *
152: * @param b1 the first boolean to compare
153: * @param b2 the second boolean to compare
154: * @return negative if obj1 is less, positive if greater, zero if equal
155: * @throws NullPointerException when either argument <code>null</code>
156: */
157: public int compare(Boolean b1, Boolean b2) {
158: boolean v1 = b1.booleanValue();
159: boolean v2 = b2.booleanValue();
160:
161: return (v1 ^ v2) ? ((v1 ^ trueFirst) ? 1 : -1) : 0;
162: }
163:
164: //-----------------------------------------------------------------------
165: /**
166: * Implement a hash code for this comparator that is consistent with
167: * {@link #equals(Object) equals}.
168: *
169: * @return a hash code for this comparator.
170: */
171: public int hashCode() {
172: int hash = "BooleanComparator".hashCode();
173: return trueFirst ? -1 * hash : hash;
174: }
175:
176: /**
177: * Returns <code>true</code> iff <i>that</i> Object is
178: * is a {@link Comparator} whose ordering is known to be
179: * equivalent to mine.
180: * <p>
181: * This implementation returns <code>true</code>
182: * iff <code><i>that</i></code> is a {@link BooleanComparator}
183: * whose value of {@link #sortsTrueFirst()} is equal to mine.
184: *
185: * @param object the object to compare to
186: * @return true if equal
187: */
188: public boolean equals(Object object) {
189: return (this == object)
190: || ((object instanceof BooleanComparator) && (this .trueFirst == ((BooleanComparator) object).trueFirst));
191: }
192:
193: //-----------------------------------------------------------------------
194: /**
195: * Returns <code>true</code> iff
196: * I sort <code>true</code> values before
197: * <code>false</code> values. In other words,
198: * returns <code>true</code> iff
199: * {@link #compare(Boolean,Boolean) compare(Boolean.FALSE,Boolean.TRUE)}
200: * returns a positive value.
201: *
202: * @return the trueFirst flag
203: */
204: public boolean sortsTrueFirst() {
205: return trueFirst;
206: }
207:
208: }
|