001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.collections.comparators;
018
019 import java.io.Serializable;
020 import java.util.Comparator;
021
022 /**
023 * A {@link Comparator} for {@link Boolean} objects that can sort either
024 * true or false first.
025 * <p>
026 * @see #getTrueFirstComparator()
027 * @see #getFalseFirstComparator()
028 * @see #getBooleanComparator(boolean)
029 *
030 * @since Commons Collections 3.0
031 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
032 *
033 * @author Rodney Waldhoff
034 */
035 public final class BooleanComparator implements Comparator, 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(true);
042
043 /** Constant "false first" reference. */
044 private static final BooleanComparator FALSE_FIRST = new BooleanComparator(false);
045
046 /** <code>true</code> iff <code>true</code> values sort before <code>false</code> values. */
047 private boolean trueFirst = false;
048
049 //-----------------------------------------------------------------------
050 /**
051 * Returns a BooleanComparator instance that sorts
052 * <code>true</code> values before <code>false</code> values.
053 * <p />
054 * Clients are encouraged to use the value returned from
055 * this method instead of constructing a new instance
056 * to reduce allocation and garbage collection overhead when
057 * multiple BooleanComparators may be used in the same
058 * virtual machine.
059 *
060 * @return the true first singleton BooleanComparator
061 */
062 public static BooleanComparator getTrueFirstComparator() {
063 return TRUE_FIRST;
064 }
065
066 /**
067 * Returns a BooleanComparator instance that sorts
068 * <code>false</code> values before <code>true</code> values.
069 * <p />
070 * Clients are encouraged to use the value returned from
071 * this method instead of constructing a new instance
072 * to reduce allocation and garbage collection overhead when
073 * multiple BooleanComparators may be used in the same
074 * virtual machine.
075 *
076 * @return the false first singleton BooleanComparator
077 */
078 public static BooleanComparator getFalseFirstComparator() {
079 return FALSE_FIRST;
080 }
081
082 /**
083 * Returns a BooleanComparator instance that sorts
084 * <code><i>trueFirst</i></code> values before
085 * <code>!<i>trueFirst</i></code> values.
086 * <p />
087 * Clients are encouraged to use the value returned from
088 * this method instead of constructing a new instance
089 * to reduce allocation and garbage collection overhead when
090 * multiple BooleanComparators may be used in the same
091 * virtual machine.
092 *
093 * @param trueFirst when <code>true</code>, sort
094 * <code>true</code> <code>Boolean</code>s before <code>false</code>
095 * @return a singleton BooleanComparator instance
096 */
097 public static BooleanComparator getBooleanComparator(boolean trueFirst) {
098 return trueFirst ? TRUE_FIRST : FALSE_FIRST;
099 }
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 }