View Javadoc

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>&#x21;<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>&#x21;<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 }